on master help sign in
Merge branch 'master' into cabal-library

Conflicts: src/Idris/DataOpts.hs

commit67da31adc2d66d0bfc79db27c875ba9905bed99a authorBrian McKenna <brian@brianmckenna.org> dateWed 18 Dec 2013, 21:50 (13 years ago) parentf27a1ff77ab9a1
45 files changed+1564−521
.gitignore+4 .travis.yml+2−1 CHANGELOG+4 CONTRIBUTING.md+117 Makefile+4−2 contribs/idrislang.sty+19−1 idris.cabal+5−4 libs/base/Control/Isomorphism.idr+122 libs/base/Data/Vect/Quantifiers.idr+2−2 libs/base/Language/Reflection.idr+2 libs/base/Syntax/PreorderReasoning.idr+15 libs/base/base.ipkg+7−2 libs/prelude/Decidable/Equality.idr+38 libs/prelude/Prelude.idr+1−1 libs/prelude/Prelude/Fin.idr+16−8 libs/prelude/Prelude/List.idr+4−5 libs/prelude/Prelude/Nat.idr+4−1 libs/prelude/Prelude/Vect.idr+30−19 src/Idris/AbsSyntax.hs+39−28 src/Idris/AbsSyntaxTree.hs+45−9 src/Idris/CaseSplit.hs+141−71 src/Idris/Completion.hs+1 src/Idris/Core/Elaborate.hs+5−2 src/Idris/Core/Evaluate.hs+1−8 src/Idris/Core/ProofState.hs+57−20 src/Idris/Core/TT.hs+15−6 src/Idris/Coverage.hs−4 src/Idris/DataOpts.hs+160−158 src/Idris/DeepSeq.hs+13−2 src/Idris/Delaborate.hs+2 src/Idris/ElabDecls.hs+354−34 src/Idris/ElabTerm.hs+17−12 src/Idris/IBC.hs+52−16 src/Idris/IdeSlave.hs+3 src/Idris/ParseData.hs+23−13 src/Idris/ParseExpr.hs+127−37 src/Idris/ParseOps.hs+23−14 src/Idris/Parser.hs+47−17 src/Idris/REPL.hs+25−18 src/Pkg/Package.hs+1−1 test/reg028/expected+2−2 test/test032/expected+3−3 test/test035/expected test/test035/run+3 test/test035/test035.idr+9
.gitignore+4
@@ -11,6 +11,8 @@ cabal.sandbox.config
1111*.swp
1212*~
1313.DS_Store
14+.hpc
15+*.tix
1416custom.mk
1517test/output
1618test/test???/output
@@ -25,3 +27,5 @@ tutorial/*.out
2527tutorial/*.toc
2628tutorial/*.fdb_latexmk
2729tutorial/*.fls
30+tags
31+TAGS
.travis.yml+2−1
@@ -19,6 +19,7 @@ script:
1919 - cabal copy
2020 - make -j2 $TESTS
2121env:
22− - TESTS=test
22+ # TESTS=doc
23+ - TESTS=test_c
2324 - TESTS=test_java
2425 - TESTS=test_llvm
CHANGELOG+4
@@ -1,3 +1,7 @@
1+New in 0.9.11:
2+-------------
3+* Agda-style equational reasoning (in Syntax.PreorderReasoning)
4+
15New in 0.9.10:
26--------------
37
CONTRIBUTING.mdnew file+117
@@ -0,0 +1,117 @@
1+# Contributing to Idris-Dev
2+
3+The Idris Community welcomes pull requests, bug reporting, and bug squashing!
4+However, we cannot do it all ourself, and want to make it as easy as possible to contribute changes to get things working.
5+Here are a few guidelines that we would like contributors to follow so that we can have a chance of keeping on top of things.
6+
7+## Getting Started
8+
9+1. Make sure you are familiar with [Git](http://git-scm.com/book).
10+1. Make sure you have a [GitHub account](https://github.com/signup/free).
11+1. Make sure you are familiar with: [Idris](http://eb.host.cs.st-andrews.ac.uk/writings/idris-tutorial.pdf).
12+1. Make sure you can install `Idris`:
13+ * [Mac OS X](https://github.com/idris-lang/Idris-dev/wiki/Idris-on-OS-X-using-Homebrew)
14+ * [Ubuntu](https://github.com/idris-lang/Idris-dev/wiki/Idris-on-Ubuntu)
15+ * [Debian](https://github.com/idris-lang/Idris-dev/wiki/Idris-on-Debian)
16+ * [Windows](https://github.com/idris-lang/Idris-dev/wiki/Idris-on-Windows)
17+
18+# Issue Reporting
19+
20+Before you report an issue, or wish to add cool functionality please try and check to see if there are existing [issues](https://github.com/idris-lang/Idris-dev/issues) and [pull requests](https://github.com/idris-lang/Idris-dev/pulls).
21+We do not want you wasting your time, duplicating somebody's work!
22+
23+## The Campsite Rule
24+
25+A basic rule when contributing to Idris is the **campsite rule**: leave the codebase in better condition than you found it.
26+Please clean up any messes that you find, and don't leave behind new messes for the next contributor.
27+
28+## Making Changes
29+
30+Idris developers and hackers try to adhere to something similar to the [successful git branching model](http://nvie.com/posts/a-successful-git-branching-model/).
31+The steps are straightforward.
32+
33+For those new to the project:
34+
35+1. Fork the `idris-dev` repo e.g.
36+
37+ $ git clone git@github.com/<your github user name>/Idris-dev.git
38+ $ git remote add upstream git@github.com:idris-lang/Idris-dev.git
39+
40+For those already contributing to the project:
41+
42+1. Ensure your existing clone is up-to-date with current HEAD e.g.
43+
44+ $ git fetch upstream
45+ $ git merge upstream/master
46+
47+The remaining steps are the same:
48+
49+1. Create, and checkout onto, a topic branch on which to base you work.
50+ * This is typically the master branch.
51+ * For your own sanity, please avoid working on the `master` branch.
52+
53+ $ git branch fix/master/my_contrib master
54+ $ git checkout fix/master/my_contrib
55+
56+1. Make commits of logical units.
57+1. Check for unnecessary whitespace with
58+
59+ $ git diff --check
60+
61+1. Make sure your commit messages are along the lines of:
62+
63+ Short (50 chars or less) summary of changes
64+
65+ More detailed explanatory text, if necessary. Wrap it to about 72
66+ characters or so. In some contexts, the first line is treated as the
67+ subject of an email and the rest of the text as the body. The blank
68+ line separating the summary from the body is critical (unless you omit
69+ the body entirely); tools like rebase can get confused if you run the
70+ two together.
71+
72+ Further paragraphs come after blank lines.
73+
74+ - Bullet points are okay, too
75+
76+ - Typically a hyphen or asterisk is used for the bullet, preceded by a
77+ single space, with blank lines in between, but conventions vary here
78+
79+1. Make sure you have added any necessary tests for your changes.
80+1. Run all the tests to assure nothing else was accidentally broken.
81+
82+ $ make test
83+
84+1. Push your changes to a topic branch in your fork of the repository.
85+
86+ $ git push origin fix/master/my_contrib
87+
88+1. Go to GitHub and submit a pull request to `idris-dev`
89+
90+From there you will have to wait on one of the `idris-dev` committers to respond to the request.
91+This response might be an accept or some changes/improvements/alternatives will be suggest.
92+We do not guarantee that all requests will be accepted.
93+
94+## Increases chances of acceptance.
95+
96+To help increase the chance of your pull request being accepted:
97+
98+1. Run the tests.
99+1. Update the documentation, the surrounding one, examples elsewhere, guides, whatever is affected by your contribution
100+1. Use appropriate code formatting for both `Idris` and `Haskell`.
101+
102+## Additional Resources
103+
104+* [Idris Wiki](https://github.com/idris-lang/Idris-dev/wiki);
105+* [Zen Of Idris](https://github.com/idris-lang/Idris-dev/wiki/The-Zen-of-Idris);
106+* Idris FAQs: [Official](http://www.idris-lang.org/documentation/faq/); [Unofficial](https://github.com/idris-lang/Idris-dev/wiki/Unofficial-FAQ);
107+* [Idris Manual](https://github.com/idris-lang/Idris-dev/wiki/Manual);
108+* [Idris Tutorial](http://eb.host.cs.st-andrews.ac.uk/writings/idris-tutorial.pdf);
109+* [Idris News](http://www.idris-lang.org/news/);
110+* [other Idris docs](http://www.idris-lang.org/documentation/).
111+* [Using Pull Requests](https://help.github.com/articles/using-pull-requests)
112+* [General GitHub Documentation](https://help.github.com/).
113+
114+
115+Adapted from the most excellent contributing files from the [Puppet project](https://github.com/puppetlabs/puppet) and [Factroy Girl Rails](https://github.com/thoughtbot/factory_girl_rails/blob/master/CONTRIBUTING.md)
116+
117+
Makefile+4−2
@@ -1,4 +1,4 @@
1−.PHONY: build configure doc install linecount nodefault pinstall lib_clean relib test
1+.PHONY: build configure doc install linecount nodefault pinstall lib_clean relib test_c test
22
33include config.mk
44-include custom.mk
@@ -13,7 +13,9 @@ pinstall: dist/setup-config
1313build: dist/setup-config
1414 $(CABAL) build $(CABALFLAGS)
1515
16−test:
16+test: doc test_c
17+
18+test_c:
1719 $(MAKE) -C test IDRIS=../dist/build/idris
1820
1921test_java:
contribs/idrislang.sty+19−1
@@ -8,6 +8,8 @@
88%% + Defines a `numbers' and `default' listings style.
99%% + Defines a `code' environment for typesetting idris.
1010%% + \begin{code}[...] ... \end{code}
11+%% + Defines an input command for externally defined idris files.
12+%% + \inputIdrisListing[...]{file.idr}
1113%% + Defines commands typesetting the name Idris.
1214%% + \Idris{}
1315%% + \idris{}
@@ -46,6 +48,8 @@
4648\lstdefinelanguage{idris}{%
4749 sensitive,%
4850%% ----------------------------------------------------------- [ Default Style ]
51+ xleftmargin=\parindent,
52+ tabsize=2,
4953 basicstyle=\ttfamily,
5054 flexiblecolumns=false,
5155 commentstyle=\footnotesize\sffamily,
@@ -163,7 +167,8 @@
163167
164168\lstdefinestyle{default}{%
165169 xleftmargin=\parindent,
166− tabsize=2
170+ tabsize=2,
171+ basicstyle=\ttfamily
167172}
168173\lstdefinestyle{numbers}{%
169174 xleftmargin=\parindent,
@@ -186,5 +191,18 @@
186191 \lstset{style=default, #1}}
187192 }
188193 {}
194+%% ---------------------------------------------------------- [ Input Listings ]
195+%% Command to add externally defined Idris code to the document.
196+\newcommand{\inputIdrisListing}[2][]{%
197+\begingroup
198+ \ifthenelse{\boolean{literate}}{%
199+ \lstset{language=literateidris}}{%
200+ \lstset{language=idris}}
201+ \ifthenelse{\boolean{numbers}}{%
202+ \lstset{style=numbers}}{%
203+ \lstset{style=default}}
204+ \lstinputlisting[#1]{#2}
205+\endgroup
206+}
189207\endinput
190208%% --------------------------------------------------------------------- [ EOF ]
idris.cabal+5−4
@@ -1,5 +1,5 @@
11Name: idris
2−Version: 0.9.10
2+Version: 0.9.10.1
33License: BSD3
44License-file: LICENSE
55Author: Edwin Brady
@@ -87,6 +87,7 @@ Extra-source-files:
8787 libs/base/Makefile
8888 libs/base/Network/*.idr
8989 libs/base/System/Concurrency/*.idr
90+ libs/base/Syntax/*.idr
9091
9192
9293 libs/effects/Makefile
@@ -102,8 +103,6 @@ Extra-source-files:
102103 llvm/*.c
103104 llvm/Makefile
104105
105− tutorial/examples/*.idr
106−
107106 test/Makefile
108107 test/runtest.pl
109108 test/reg001/run
@@ -286,6 +285,9 @@ Extra-source-files:
286285 test/test033/expected
287286 test/test034/run
288287 test/test034/expected
288+ test/test035/run
289+ test/test035/expected
290+ test/test035/*.idr
289291
290292source-repository head
291293 type: git
@@ -511,7 +513,6 @@ Executable idris
511513 , haskeline >= 0.7
512514 , language-java >= 0.2.6
513515 , mtl
514− --, parsec >= 3
515516 , parsers == 0.9
516517 , pretty
517518 , process
libs/base/Control/Isomorphism.idrnew file+122
@@ -0,0 +1,122 @@
1+module Control.Isomorphism
2+
3+import Syntax.PreorderReasoning
4+
5+%default total
6+
7+-- An isomorphism between two types
8+data Iso : Type -> Type -> Type where
9+ MkIso : (to : a -> b) ->
10+ (from : b -> a) ->
11+ (toFrom : (y : b) -> to (from y) = y) ->
12+ (fromTo : (x : a) -> from (to x) = x) ->
13+ Iso a b
14+
15+-- Isomorphism properties
16+
17+isoRefl : Iso a a
18+isoRefl = MkIso id id (\x => refl) (\x => refl)
19+
20+isoTrans : Iso a b -> Iso b c -> Iso a c
21+isoTrans (MkIso to from toFrom fromTo) (MkIso to' from' toFrom' fromTo') =
22+ MkIso (\x => to' (to x))
23+ (\y => from (from' y))
24+ (\y => (to' (to (from (from' y)))) ={ cong (toFrom (from' y)) }=
25+ (to' (from' y)) ={ toFrom' y }=
26+ y QED)
27+ (\x => (from (from' (to' (to x)))) ={ cong (fromTo' (to x)) }=
28+ (from (to x)) ={ fromTo x }=
29+ x QED)
30+
31+
32+
33+-- Isomorphisms over sums
34+
35+eitherComm : Iso (Either a b) (Either b a)
36+eitherComm = MkIso swap swap swapSwap swapSwap
37+ where swap : Either a b -> Either b a
38+ swap (Left x) = Right x
39+ swap (Right x) = Left x
40+ swapSwap : (e : Either a b) -> swap (swap e) = e
41+ swapSwap (Left x) = refl
42+ swapSwap (Right x) = refl
43+
44+eitherAssoc : Iso (Either (Either a b) c) (Either a (Either b c))
45+eitherAssoc = MkIso eitherAssoc1 eitherAssoc2 ok1 ok2
46+ where eitherAssoc1 : Either (Either a b) c -> Either a (Either b c)
47+ eitherAssoc1 (Left (Left x)) = Left x
48+ eitherAssoc1 (Left (Right x)) = Right (Left x)
49+ eitherAssoc1 (Right x) = Right (Right x)
50+
51+ eitherAssoc2 : Either a (Either b c) -> Either (Either a b) c
52+ eitherAssoc2 (Left x) = Left (Left x)
53+ eitherAssoc2 (Right (Left x)) = Left (Right x)
54+ eitherAssoc2 (Right (Right x)) = Right x
55+
56+ ok1 : (x : Either a (Either b c)) -> eitherAssoc1 (eitherAssoc2 x) = x
57+ ok1 (Left x) = refl
58+ ok1 (Right (Left x)) = refl
59+ ok1 (Right (Right x)) = refl
60+
61+ ok2 : (x : Either (Either a b) c) -> eitherAssoc2 (eitherAssoc1 x) = x
62+ ok2 (Left (Left x)) = refl
63+ ok2 (Left (Right x)) = refl
64+ ok2 (Right x) = refl
65+
66+eitherBotLeft : Iso (Either _|_ a) a
67+eitherBotLeft = MkIso to from ok1 ok2
68+ where to : Either _|_ a -> a
69+ to (Left x) = FalseElim x
70+ to (Right x) = x
71+ from : a -> Either _|_ a
72+ from = Right
73+ ok1 : (x : a) -> to (from x) = x
74+ ok1 x = refl
75+ ok2 : (x : Either _|_ a) -> from (to x) = x
76+ ok2 (Left x) = FalseElim x
77+ ok2 (Right x) = refl
78+
79+eitherBotRight : Iso (Either a _|_) a
80+eitherBotRight = isoTrans eitherComm eitherBotLeft
81+
82+-- Isomorphisms over products
83+pairComm : Iso (a, b) (b, a)
84+pairComm = MkIso swap swap swapSwap swapSwap
85+ where swap : (a, b) -> (b, a)
86+ swap (x, y) = (y, x)
87+ swapSwap : (x : (a, b)) -> swap (swap x) = x
88+ swapSwap (x, y) = refl
89+
90+pairAssoc : Iso (a, (b, c)) ((a, b), c)
91+pairAssoc = MkIso to from ok1 ok2
92+ where
93+ to : (a, (b, c)) -> ((a, b), c)
94+ to (x, (y, z)) = ((x, y), z)
95+ from : ((a, b), c) -> (a, (b, c))
96+ from ((x, y), z) = (x, (y, z))
97+ ok1 : (x : ((a, b), c)) -> to (from x) = x
98+ ok1 ((x, y), z) = refl
99+ ok2 : (x : (a, (b, c))) -> from (to x) = x
100+ ok2 (x, (y, z)) = refl
101+
102+pairUnitRight : Iso (a, ()) a
103+pairUnitRight = MkIso fst (\x => (x, ())) (\x => refl) ok
104+ where ok : (x : (a, ())) -> (fst x, ()) = x
105+ ok (x, ()) = refl
106+
107+pairUnitLeft : Iso ((), a) a
108+pairUnitLeft = isoTrans pairComm pairUnitRight
109+
110+pairBotLeft : Iso (_|_, a) _|_
111+pairBotLeft = MkIso fst FalseElim (\x => FalseElim x) (\y => FalseElim (fst y))
112+
113+pairBotRight : Iso (a, _|_) _|_
114+pairBotRight = isoTrans pairComm pairBotLeft
115+
116+
117+-- Enable preorder reasoning syntax over isomorphisms
118+qed : (a : Type) -> Iso a a
119+qed a = isoRefl
120+
121+step : (a : Type) -> Iso a b -> Iso b c -> Iso a c
122+step a iso1 iso2 = isoTrans iso1 iso2
libs/base/Data/Vect/Quantifiers.idr+2−2
@@ -5,8 +5,8 @@ data Any : (P : a -> Type) -> Vect n a -> Type where
55 There : {P : a -> Type} -> {xs : Vect n a} -> Any P xs -> Any P (x :: xs)
66
77anyNilAbsurd : {P : a -> Type} -> Any P Nil -> _|_
8−anyNilAbsurd Here impossible
9−anyNilAbsurd There impossible
8+anyNilAbsurd (Here _) impossible
9+anyNilAbsurd (There _) impossible
1010
1111anyElim : {xs : Vect n a} -> {P : a -> Type} -> (Any P xs -> b) -> (P x -> b) -> Any P (x :: xs) -> b
1212anyElim _ f (Here p) = f p
libs/base/Language/Reflection.idr+2
@@ -177,6 +177,8 @@ data Tactic = Try Tactic Tactic
177177 -- ^ focus a named hole
178178 | Rewrite TT
179179 -- ^ rewrite using the reflected rep. of a equality proof
180+ | Induction TTName
181+ -- ^ do induction on the particular expression
180182 | LetTac TTName TT
181183 -- ^ name a reflected term
182184 | LetTacTy TTName TT TT
libs/base/Syntax/PreorderReasoning.idrnew file+15
@@ -0,0 +1,15 @@
1+module Syntax.PreorderReasoning
2+
3+-- QED is first to get the precedence to work out. It's just refl with an explicit argument.
4+syntax [expr] "QED" = qed expr
5+-- foo ={ prf }= bar ={ prf' }= fnord QED
6+-- is a proof that foo is related to fnord, with the intermediate step being bar, justified by prf and prf'
7+syntax [from] "={" [prf] "}=" [to] = step from prf to
8+
9+namespace Equal
10+ using (a : Type, x : a, y : a, z : a)
11+ qed : (x : a) -> x = x
12+ qed x = the (x = x) refl
13+ step : (x : a) -> x = y -> (y = z) -> x = z
14+ step x refl refl = refl
15+
libs/base/base.ipkg+7−2
@@ -16,15 +16,20 @@ modules = System,
1616
1717 Language.Reflection, Language.Reflection.Utils, Language.Reflection.Errors,
1818
19− Data.Morphisms,
20− Data.Bits, Data.Mod2,
19+ Syntax.PreorderReasoning,
20+
21+ Data.Morphisms,
22+ Data.Bits, Data.Mod2,
2123 Data.ZZ, Data.Sign,
2224 Data.SortedMap, Data.SortedSet, Data.BoundedList,
2325 Data.Vect, Data.HVect, Data.Vect.Quantifiers,
2426 Data.Floats, Data.Complex, Data.Heap,
2527
28+ Control.Isomorphism,
2629 Control.Monad.Identity,
2730 Control.Monad.RWS,
2831 Control.Monad.State, Control.Monad.Writer, Control.Monad.Reader,
2932 Control.Category, Control.Arrow,
3033 Control.Catchable, Control.IOExcept
34+
35+
libs/prelude/Decidable/Equality.idr+38
@@ -1,6 +1,7 @@
11module Decidable.Equality
22
33import Builtins
4+import Prelude.Basics
45import Prelude.Either
56import Prelude.List
67import Prelude.Vect
@@ -177,3 +178,40 @@ instance DecEq a => DecEq (Vect n a) where
177178 decEq (x :: xs) (x :: xs) | (Yes refl, Yes refl) = Yes refl
178179 decEq (x :: xs) (y :: ys) | (_, No nEqTl) = No (\p => nEqTl (vectInjective2 p))
179180 decEq (x :: xs) (y :: ys) | (No nEqHd, _) = No (\p => nEqHd (vectInjective1 p))
181+
182+
183+-- For the primitives, we have to cheat because we don't have access to their
184+-- internal implementations.
185+
186+--------------------------------------------------------------------------------
187+-- Int
188+--------------------------------------------------------------------------------
189+
190+instance DecEq Int where
191+ decEq x y = if x == y then Yes (really_believe_me {a = x=x} {b = x=y} refl)
192+ else No (really_believe_me _|_)
193+
194+--------------------------------------------------------------------------------
195+-- Char
196+--------------------------------------------------------------------------------
197+
198+instance DecEq Char where
199+ decEq x y = if x == y then Yes (really_believe_me {a = x=x} {b = x=y} refl)
200+ else No (really_believe_me _|_)
201+
202+--------------------------------------------------------------------------------
203+-- Integer
204+--------------------------------------------------------------------------------
205+
206+instance DecEq Integer where
207+ decEq x y = if x == y then Yes (really_believe_me {a = x=x} {b = x=y} refl)
208+ else No (really_believe_me _|_)
209+
210+--------------------------------------------------------------------------------
211+-- Float
212+--------------------------------------------------------------------------------
213+
214+instance DecEq Float where
215+ decEq x y = if x == y then Yes (really_believe_me {a = x=x} {b = x=y} refl)
216+ else No (really_believe_me _|_)
217+
libs/prelude/Prelude.idr+1−1
@@ -410,7 +410,7 @@ syntax "[" [start] "," [next] ".." [end] "]"
410410 = enumFromThenTo start (next - start) end
411411
412412syntax "[" [start] "..]"
413− = enumFrom start 1
413+ = enumFrom start
414414syntax "[" [start] "," [next] "..]"
415415 = enumFromThen start (next - start)
416416
libs/prelude/Prelude/Fin.idr+16−8
@@ -3,6 +3,8 @@ module Prelude.Fin
33import Prelude.Nat
44import Prelude.Either
55
6+%default total
7+
68data Fin : Nat -> Type where
79 fZ : Fin (S k)
810 fS : Fin k -> Fin (S k)
@@ -12,19 +14,25 @@ instance Eq (Fin n) where
1214 (==) (fS k) (fS k') = k == k'
1315 (==) _ _ = False
1416
15−finToNat : Fin n -> Nat -> Nat
16−finToNat fZ a = a
17−finToNat (fS x) a = finToNat x (S a)
17+FinZAbsurd : Fin Z -> _|_
18+FinZAbsurd fZ impossible
19+
20+FinZElim : Fin Z -> a
21+FinZElim x = FalseElim (FinZAbsurd x)
22+
23+finToNat : Fin n -> Nat
24+finToNat fZ = Z
25+finToNat (fS k) = S (finToNat k)
1826
1927instance Cast (Fin n) Nat where
20− cast x = finToNat x Z
28+ cast x = finToNat x
2129
22−finToInt : Fin n -> Integer -> Integer
23−finToInt fZ a = a
24−finToInt (fS x) a = finToInt x (a + 1)
30+finToInteger : Fin n -> Integer
31+finToInteger fZ = 0
32+finToInteger (fS k) = 1 + finToInteger k
2533
2634instance Cast (Fin n) Integer where
27− cast x = finToInt x 0
35+ cast x = finToInteger x
2836
2937weaken : Fin n -> Fin (S n)
3038weaken fZ = fZ
libs/prelude/Prelude/List.idr+4−5
@@ -15,10 +15,13 @@ import Prelude.Nat
1515infixr 7 ::
1616infixl 8 ++
1717
18−data List a
18+%elim data List a
1919 = Nil
2020 | (::) a (List a)
2121
22+-- Name hints for interactive editing
23+%name List xs, ys, zs, ws
24+
2225--------------------------------------------------------------------------------
2326-- Syntactic tests
2427--------------------------------------------------------------------------------
@@ -461,10 +464,6 @@ sort xs =
461464-- Conversions
462465--------------------------------------------------------------------------------
463466
464−maybeToList : Maybe a -> List a
465−maybeToList Nothing = []
466−maybeToList (Just j) = [j]
467−
468467listToMaybe : List a -> Maybe a
469468listToMaybe [] = Nothing
470469listToMaybe (x::xs) = Just x
libs/prelude/Prelude/Nat.idr+4−1
@@ -10,10 +10,13 @@ import Prelude.Classes
1010%access public
1111%default total
1212
13−data Nat
13+%elim data Nat
1414 = Z
1515 | S Nat
1616
17+-- name hints for interactive editing
18+%name Nat k,j,i,n,m
19+
1720--------------------------------------------------------------------------------
1821-- Syntactic tests
1922--------------------------------------------------------------------------------
libs/prelude/Prelude/Vect.idr+30−19
@@ -11,9 +11,12 @@ import Prelude.Nat
1111
1212infixr 7 ::
1313
14−data Vect : Nat -> Type -> Type where
14+%elim data Vect : Nat -> Type -> Type where
1515 Nil : Vect Z a
16− (::) : a -> Vect n a -> Vect (S n) a
16+ (::) : (x : a) -> (xs : Vect n a) -> Vect (S n) a
17+
18+-- Hints for interactive editing
19+%name Vect xs,ys,zs,ws
1720
1821--------------------------------------------------------------------------------
1922-- Indexing into vectors
@@ -51,15 +54,14 @@ replaceAt (fS k) y (x::xs) = x :: replaceAt k y xs
5154-- Subvectors
5255--------------------------------------------------------------------------------
5356
54−take : Fin n -> Vect n a -> (p ** Vect p a)
55−take fZ xs = (_ ** [])
56−take (fS k) [] impossible
57−take (fS k) (x::xs) with (take k xs)
58− | (_ ** tail) = (_ ** x::tail)
57+take : {n : Nat} -> (m : Fin (S n)) -> Vect n a -> Vect (cast m) a
58+take (fS k) [] = FinZElim k
59+take fZ _ = []
60+take (fS k) (x::xs) = x :: take k xs
5961
60−drop : Fin n -> Vect n a -> (p ** Vect p a)
61−drop fZ xs = (_ ** xs)
62−drop (fS k) [] impossible
62+drop : (m : Fin (S n)) -> Vect n a -> Vect (n - cast m) a
63+drop (fS k) [] = FinZElim k
64+drop fZ xs ?= xs
6365drop (fS k) (x::xs) = drop k xs
6466
6567--------------------------------------------------------------------------------
@@ -143,15 +145,13 @@ reverse = reverse' []
143145 reverse' acc [] ?= acc
144146 reverse' acc (x::xs) ?= reverse' (x::acc) xs
145147
146−total intersperse' : a -> Vect m a -> (p ** Vect p a)
147−intersperse' sep [] = (_ ** [])
148−intersperse' sep (y::ys) with (intersperse' sep ys)
149− | (_ ** tail) = (_ ** sep::y::tail)
150−
151−total intersperse : a -> Vect m a -> (p ** Vect p a)
152−intersperse sep [] = (_ ** [])
153−intersperse sep (x::xs) with (intersperse' sep xs)
154− | (_ ** tail) = (_ ** x::tail)
148+intersperse : a -> Vect n a -> Vect (n + pred n) a
149+intersperse sep [] = []
150+intersperse sep (x::xs) = x :: intersperse' sep xs
151+ where
152+ intersperse' : a -> Vect n a -> Vect (n + n) a
153+ intersperse' sep [] = []
154+ intersperse' sep (x::xs) ?= sep :: x :: intersperse' sep xs
155155
156156--------------------------------------------------------------------------------
157157-- Membership tests
@@ -311,6 +311,12 @@ range {n=S _} = fZ :: map fS range
311311-- Proofs
312312--------------------------------------------------------------------------------
313313
314+Prelude.Vect.drop_lemma_1 = proof {
315+ intros;
316+ rewrite sym (minusZeroRight n);
317+ trivial;
318+}
319+
314320Prelude.Vect.reverse'_lemma_2 = proof {
315321 intros;
316322 rewrite (plusSuccRightSucc m n1);
@@ -323,3 +329,8 @@ Prelude.Vect.reverse'_lemma_1 = proof {
323329 exact value;
324330}
325331
332+Prelude.Vect.intersperse'_lemma_1 = proof {
333+ intros;
334+ rewrite (plusSuccRightSucc n1 n1);
335+ trivial;
336+}
src/Idris/AbsSyntax.hs+39−28
@@ -167,6 +167,25 @@ addDocStr n doc
167167 = do i <- getIState
168168 putIState $ i { idris_docstrings = addDef n doc (idris_docstrings i) }
169169
170+addNameHint :: Name -> Name -> Idris ()
171+addNameHint ty n
172+ = do i <- getIState
173+ ty' <- case lookupCtxtName ty (idris_implicits i) of
174+ [(tyn, _)] -> return tyn
175+ [] -> throwError (NoSuchVariable ty)
176+ tyns -> throwError (CantResolveAlts (map show (map fst tyns)))
177+ let ns' = case lookupCtxt ty' (idris_namehints i) of
178+ [ns] -> ns ++ [n]
179+ _ -> [n]
180+ putIState $ i { idris_namehints = addDef ty' ns' (idris_namehints i) }
181+
182+getNameHints :: IState -> Name -> [Name]
183+getNameHints i (UN "->") = [UN "f",UN "g"]
184+getNameHints i n =
185+ case lookupCtxt n (idris_namehints i) of
186+ [ns] -> ns
187+ _ -> []
188+
170189addToCalledG :: Name -> [Name] -> Idris ()
171190addToCalledG n ns = return () -- TODO
172191
@@ -178,10 +197,10 @@ addInstance :: Bool -> Name -> Name -> Idris ()
178197addInstance int n i
179198 = do ist <- getIState
180199 case lookupCtxt n (idris_classes ist) of
181− [CI a b c d ins] ->
182− do let cs = addDef n (CI a b c d (addI i ins)) (idris_classes ist)
200+ [CI a b c d e ins] ->
201+ do let cs = addDef n (CI a b c d e (addI i ins)) (idris_classes ist)
183202 putIState $ ist { idris_classes = cs }
184− _ -> do let cs = addDef n (CI (MN 0 "none") [] [] [] [i]) (idris_classes ist)
203+ _ -> do let cs = addDef n (CI (MN 0 "none") [] [] [] [] [i]) (idris_classes ist)
185204 putIState $ ist { idris_classes = cs }
186205 where addI i ins | int = i : ins
187206 | chaser n = ins ++ [i]
@@ -371,7 +390,7 @@ ihWarn :: Handle -> FC -> String -> Idris ()
371390ihWarn h fc err = do i <- getIState
372391 case idris_outputmode i of
373392 RawOutput -> runIO $ hPutStrLn h (show fc ++ ":" ++ err)
374− IdeSlave n -> runIO $ hPutStrLn h $ convSExp "warning" (fc_fname fc, fc_line fc, err) n
393+ IdeSlave n -> runIO $ hPutStrLn h $ convSExp "warning" (fc_fname fc, fc_line fc, fc_column fc, err) n
375394
376395setLogLevel :: Int -> Idris ()
377396setLogLevel l = do i <- getIState
@@ -631,11 +650,12 @@ inferTy = MN 0 "__Infer"
631650inferCon = MN 0 "__infer"
632651inferDecl = PDatadecl inferTy
633652 PType
634− [("", inferCon, PPi impl (MN 0 "A") PType (
635− PPi expl (MN 0 "a") (PRef bi (MN 0 "A"))
653+ [("", inferCon, PPi impl (MN 0 "iType") PType (
654+ PPi expl (MN 0 "ival") (PRef bi (MN 0 "iType"))
636655 (PRef bi inferTy)), bi)]
656+inferOpts = []
637657
638−infTerm t = PApp bi (PRef bi inferCon) [pimp (MN 0 "A") Placeholder True, pexp t]
658+infTerm t = PApp bi (PRef bi inferCon) [pimp (MN 0 "iType") Placeholder True, pexp t]
639659infP = P (TCon 6 0) inferTy (TType (UVal 0))
640660
641661getInferTerm, getInferType :: Term -> Term
@@ -646,7 +666,7 @@ getInferTerm tm = tm -- error ("getInferTerm " ++ show tm)
646666getInferType (Bind n b sc) = Bind n b $ getInferType sc
647667getInferType (App (App _ ty) _) = ty
648668
649−-- Handy primitives: Unit, False, Pair, MkPair, =, mkForeign
669+-- Handy primitives: Unit, False, Pair, MkPair, =, mkForeign, Elim type class
650670
651671primNames = [unitTy, unitCon,
652672 falseTy, pairTy, pairCon,
@@ -656,9 +676,11 @@ unitTy = MN 0 "__Unit"
656676unitCon = MN 0 "__II"
657677unitDecl = PDatadecl unitTy PType
658678 [("", unitCon, PRef bi unitTy, bi)]
679+unitOpts = [DefaultEliminator]
659680
660681falseTy = MN 0 "__False"
661682falseDecl = PDatadecl falseTy PType []
683+falseOpts = []
662684
663685pairTy = MN 0 "__Pair"
664686pairCon = MN 0 "__MkPair"
@@ -670,6 +692,7 @@ pairDecl = PDatadecl pairTy (piBind [(n "A", PType), (n "B", PType)] PType)
670692 (PApp bi (PRef bi pairTy) [pexp (PRef bi (n "A")),
671693 pexp (PRef bi (n "B"))])))), bi)]
672694 where n a = MN 0 a
695+pairOpts = []
673696
674697eqTy = UN "="
675698eqCon = UN "refl"
@@ -683,6 +706,14 @@ eqDecl = PDatadecl eqTy (piBind [(n "a", PType), (n "b", PType),
683706 pexp (PRef bi (n "x")),
684707 pexp (PRef bi (n "x"))])), bi)]
685708 where n a = MN 0 a
709+eqOpts = []
710+
711+elimName = UN "__Elim"
712+elimMethElimTy = UN "__elimTy"
713+elimMethElim = UN "elim"
714+elimDecl = PClass "Type class for eliminators" defaultSyntax bi [] elimName [(UN "scrutineeType", PType)]
715+ [PTy "" defaultSyntax bi [TotalFn] elimMethElimTy PType,
716+ PTy "" defaultSyntax bi [TotalFn] elimMethElim (PRef bi elimMethElimTy)]
686717
687718-- Defined in builtins.idr
688719sigmaTy = UN "Exists"
@@ -1361,26 +1392,6 @@ findStatics ist tm = trace (showImp Nothing True False tm) $
13611392 return (PPi p n t sc')
13621393 pos ns ss t = return t
13631394
1364−-- Debugging/logging stuff
1365−
1366−dumpDecls :: [PDecl] -> String
1367−dumpDecls [] = ""
1368−dumpDecls (d:ds) = dumpDecl d ++ "\n" ++ dumpDecls ds
1369−
1370−dumpDecl (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
1371−dumpDecl (PTy _ _ _ _ n t) = "tydecl " ++ show n ++ " : " ++ showImp Nothing True False t
1372−dumpDecl (PClauses _ _ n cs) = "pat " ++ show n ++ "\t" ++ showSep "\n\t" (map (showCImp True) cs)
1373−dumpDecl (PData _ _ _ _ d) = showDImp True d
1374−dumpDecl (PParams _ ns ps) = "params {" ++ show ns ++ "\n" ++ dumpDecls ps ++ "}\n"
1375−dumpDecl (PNamespace n ps) = "namespace {" ++ n ++ "\n" ++ dumpDecls ps ++ "}\n"
1376−dumpDecl (PSyntax _ syn) = "syntax " ++ show syn
1377−dumpDecl (PClass _ _ _ cs n ps ds)
1378− = "class " ++ show cs ++ " " ++ show n ++ " " ++ show ps ++ "\n" ++ dumpDecls ds
1379−dumpDecl (PInstance _ _ cs n _ t _ ds)
1380− = "instance " ++ show cs ++ " " ++ show n ++ " " ++ show t ++ "\n" ++ dumpDecls ds
1381−dumpDecl _ = "..."
1382−-- dumpDecl (PImport i) = "import " ++ i
1383−
13841395-- for 6.12/7 compatibility
13851396data EitherErr a b = LeftErr a | RightOK b
13861397
src/Idris/AbsSyntaxTree.hs+45−9
@@ -92,6 +92,7 @@ data IState = IState {
9292 idris_dsls :: Ctxt DSL,
9393 idris_optimisation :: Ctxt OptInfo,
9494 idris_datatypes :: Ctxt TypeInfo,
95+ idris_namehints :: Ctxt [Name],
9596 idris_patdefs :: Ctxt ([([Name], Term, Term)], [PTerm]), -- not exported
9697 -- ^ list of lhs/rhs, and a list of missing clauses
9798 idris_flags :: Ctxt [FnOpt],
@@ -183,12 +184,14 @@ data IBCWrite = IBCFix FixDecl
183184 | IBCDoc Name
184185 | IBCCoercion Name
185186 | IBCDef Name -- i.e. main context
187+ | IBCNameHint (Name, Name)
186188 | IBCLineApp FilePath Int PTerm
187189 deriving Show
188190
189191idrisInit = IState initContext [] [] emptyContext emptyContext emptyContext
190192 emptyContext emptyContext emptyContext emptyContext
191193 emptyContext emptyContext emptyContext emptyContext
194+ emptyContext
192195 [] [] defaultOpts 6 [] [] [] [] [] [] [] [] [] [] [] []
193196 [] Nothing Nothing [] [] [] Hidden False [] Nothing [] [] RawOutput
194197 True defaultTheme stdout
@@ -392,6 +395,14 @@ inlinable = elem Inlinable
392395dictionary :: FnOpts -> Bool
393396dictionary = elem Dictionary
394397
398+
399+-- | Data declaration options
400+data DataOpt = Codata -- Set if the the data-type is coinductive
401+ | DefaultEliminator -- Set if an eliminator should be generated for data type
402+ deriving (Show, Eq)
403+
404+type DataOpts = [DataOpt]
405+
395406-- | Top-level declarations such as compiler directives, definitions,
396407-- datatypes and typeclasses.
397408data PDecl' t
@@ -400,7 +411,7 @@ data PDecl' t
400411 | PPostulate String SyntaxInfo FC FnOpts Name t -- ^ Postulate
401412 | PClauses FC FnOpts Name [PClause' t] -- ^ Pattern clause
402413 | PCAF FC Name t -- ^ Top level constant
403− | PData String SyntaxInfo FC Bool (PData' t) -- ^ Data declaration. The Bool argument is True for codata.
414+ | PData String SyntaxInfo FC DataOpts (PData' t) -- ^ Data declaration.
404415 | PParams FC [(Name, t)] [PDecl' t] -- ^ Params block
405416 | PNamespace String [PDecl' t] -- ^ New namespace
406417 | PRecord String SyntaxInfo FC Name t String Name t -- ^ Record declaration
@@ -627,6 +638,7 @@ mapPT f t = f (mpt t) where
627638
628639data PTactic' t = Intro [Name] | Intros | Focus Name
629640 | Refine Name [Bool] | Rewrite t
641+ | Induction Name
630642 | Equiv t
631643 | MatchRefine Name
632644 | LetTac Name t | LetTacTy Name t t
@@ -654,6 +666,7 @@ instance Sized a => Sized (PTactic' a) where
654666 size (Focus nm) = 1 + size nm
655667 size (Refine nm bs) = 1 + size nm + length bs
656668 size (Rewrite t) = 1 + size t
669+ size (Induction t) = 1 + size t
657670 size (LetTac nm t) = 1 + size nm + size t
658671 size (Exact t) = 1 + size t
659672 size Compute = 1
@@ -737,6 +750,7 @@ type PArg = PArg' PTerm
737750data ClassInfo = CI { instanceName :: Name,
738751 class_methods :: [(Name, (FnOpts, PTerm))],
739752 class_defaults :: [(Name, (Name, PDecl))], -- method name -> default impl
753+ class_default_superclasses :: [PDecl],
740754 class_params :: [Name],
741755 class_instances :: [Name] }
742756 deriving Show
@@ -745,9 +759,21 @@ deriving instance Binary ClassInfo
745759deriving instance NFData ClassInfo
746760!-}
747761
762+-- An argument is conditionally forceable iff its forceability
763+-- depends on the collapsibility of the whole type.
764+data Forceability = Conditional | Unconditional deriving (Show, Enum, Bounded, Eq, Ord)
765+
766+{-!
767+deriving instance Binary Forceability
768+deriving instance NFData Forceability
769+!-}
770+
748771data OptInfo = Optimise { collapsible :: Bool,
749772 isnewtype :: Bool,
750− forceable :: [Int], -- argument positions
773+ -- The following should actually be (IntMap Forceability)
774+ -- but the corresponding Binary instance seems to be broken.
775+ -- Let's store a list and convert it to IntMap whenever needed.
776+ forceable :: [(Int, Forceability)],
751777 recursive :: [Int] }
752778 deriving Show
753779{-!
@@ -869,13 +895,23 @@ instance Show PClause where
869895instance Show PData where
870896 show d = showDImp False d
871897
898+showDecls :: Bool -> [PDecl] -> String
899+showDecls _ [] = ""
900+showDecls i (d:ds) = showDeclImp i d ++ "\n" ++ showDecls i ds
901+
872902showDeclImp _ (PFix _ f ops) = show f ++ " " ++ showSep ", " ops
873−showDeclImp t (PTy _ _ _ _ n ty) = show n ++ " : " ++ showImp Nothing t False ty
874−showDeclImp t (PPostulate _ _ _ _ n ty) = show n ++ " : " ++ showImp Nothing t False ty
875−showDeclImp _ (PClauses _ _ n c) = showSep "\n" (map show c)
876−showDeclImp _ (PData _ _ _ _ d) = show d
877−showDeclImp _ (PParams f ns ps) = "parameters " ++ show ns ++ "\n" ++
878− showSep "\n" (map show ps)
903+showDeclImp i (PTy _ _ _ _ n t) = "tydecl " ++ showCG n ++ " : " ++ showImp Nothing i False t
904+showDeclImp i (PClauses _ _ n cs) = "pat " ++ showCG n ++ "\t" ++ showSep "\n\t" (map (showCImp i) cs)
905+showDeclImp _ (PData _ _ _ _ d) = showDImp True d
906+showDeclImp i (PParams _ ns ps) = "params {" ++ show ns ++ "\n" ++ showDecls i ps ++ "}\n"
907+showDeclImp i (PNamespace n ps) = "namespace {" ++ n ++ "\n" ++ showDecls i ps ++ "}\n"
908+showDeclImp _ (PSyntax _ syn) = "syntax " ++ show syn
909+showDeclImp i (PClass _ _ _ cs n ps ds)
910+ = "class " ++ show cs ++ " " ++ show n ++ " " ++ show ps ++ "\n" ++ showDecls i ds
911+showDeclImp i (PInstance _ _ cs n _ t _ ds)
912+ = "instance " ++ show cs ++ " " ++ show n ++ " " ++ show t ++ "\n" ++ showDecls i ds
913+showDeclImp _ _ = "..."
914+-- showDeclImp (PImport i) = "import " ++ i
879915
880916
881917showCImp :: Bool -> PClause -> String
@@ -1121,7 +1157,7 @@ showName ist bnd impl colour n = case ist of
11211157 Just i -> if colour then colourise n (idris_colourTheme i) else showbasic n
11221158 Nothing -> showbasic n
11231159 where name = if impl then show n else showbasic n
1124− showbasic n@(UN _) = show n
1160+ showbasic n@(UN _) = showCG n
11251161 showbasic (MN _ s) = s
11261162 showbasic (NS n s) = showSep "." (reverse s) ++ "." ++ showbasic n
11271163 showbasic (SN s) = show s
src/Idris/CaseSplit.hs+141−71
@@ -3,6 +3,7 @@
33module Idris.CaseSplit(splitOnLine, replaceSplits,
44 getClause, getProofClause,
55 mkWith,
6+ nameMissing,
67 getUniq, nameRoot) where
78
89-- splitting a variable in a pattern clause
@@ -71,38 +72,68 @@ split n t'
7172 logLvl 3 ("Split:\n" ++
7273 (showSep "\n" (map show (mapMaybe id newPats))))
7374 logLvl 3 "----"
74− let newPats' = mergeAllPats ctxt t (mapMaybe id newPats)
75+ let newPats' = mergeAllPats ist n t (mapMaybe id newPats)
7576 iLOG ("Name updates " ++ showSep "\n"
7677 (map (\ (p, u) -> show u ++ " " ++ show p) newPats'))
7778 return (map snd newPats')
7879
7980data MergeState = MS { namemap :: [(Name, Name)],
81+ invented :: [(Name, Name)],
82+ explicit :: [Name],
8083 updates :: [(Name, PTerm)] }
8184
8285addUpdate n tm = do ms <- get
8386 put (ms { updates = ((n, stripNS tm) : updates ms) } )
8487
88+inventName ist ty n =
89+ do ms <- get
90+ let supp = case ty of
91+ Nothing -> []
92+ Just t -> getNameHints ist t
93+ let nsupp = case n of
94+ MN i ('_':_) -> mkSupply (supp ++ varlist)
95+ MN i n -> mkSupply (UN n : supp ++ varlist)
96+ x -> mkSupply (x : supp)
97+ let badnames = map snd (namemap ms) ++ map snd (invented ms) ++
98+ explicit ms
99+ case lookup n (invented ms) of
100+ Just n' -> return n'
101+ Nothing ->
102+ do let n' = uniqueNameFrom nsupp badnames
103+ put (ms { invented = (n, n') : invented ms })
104+ return n'
105+
106+mkSupply ns = mkSupply' ns (map nextName ns)
107+ where mkSupply' xs ns' = xs ++ mkSupply ns'
108+
109+varlist = map (UN . (:[])) "xyzwstuv" -- EB's personal preference :)
110+
85111stripNS tm = mapPT dens tm where
86112 dens (PRef fc n) = PRef fc (nsroot n)
87113 dens t = t
88114
89−mergeAllPats :: Context -> PTerm -> [PTerm] -> [(PTerm, [(Name, PTerm)])]
90−mergeAllPats ctxt t [] = []
91−mergeAllPats ctxt t (p : ps)
92− = let (p', MS _ u) = runState (mergePat ctxt t p) (MS [] [])
93− ps' = mergeAllPats ctxt t ps in
94− ((p, u) : ps')
95−
96−mergePat :: Context -> PTerm -> PTerm -> State MergeState PTerm
115+mergeAllPats :: IState -> Name -> PTerm -> [PTerm] -> [(PTerm, [(Name, PTerm)])]
116+mergeAllPats ist cv t [] = []
117+mergeAllPats ist cv t (p : ps)
118+ = let (p', MS _ _ _ u) = runState (mergePat ist t p Nothing)
119+ (MS [] [] (filter (/=cv) (patvars t)) [])
120+ ps' = mergeAllPats ist cv t ps in
121+ ((p', u) : ps')
122+ where patvars (PRef _ n) = [n]
123+ patvars (PApp _ _ as) = concatMap (patvars . getTm) as
124+ patvars (PPatvar _ n) = [n]
125+ patvars _ = []
126+
127+mergePat :: IState -> PTerm -> PTerm -> Maybe Name -> State MergeState PTerm
97128-- If any names are unified, make sure they stay unified. Always prefer
98129-- user provided name (first pattern)
99−mergePat ctxt (PPatvar fc n) new
100− = mergePat ctxt (PRef fc n) new
101−mergePat ctxt old (PPatvar fc n)
102− = mergePat ctxt old (PRef fc n)
103−mergePat ctxt orig@(PRef fc n) new@(PRef _ n')
104− | isDConName n' ctxt = do addUpdate n new;
105− return new
130+mergePat ist (PPatvar fc n) new t
131+ = mergePat ist (PRef fc n) new t
132+mergePat ist old (PPatvar fc n) t
133+ = mergePat ist old (PRef fc n) t
134+mergePat ist orig@(PRef fc n) new@(PRef _ n') t
135+ | isDConName n' (tt_ctxt ist) = do addUpdate n new
136+ return new
106137 | otherwise
107138 = do ms <- get
108139 case lookup n' (namemap ms) of
@@ -110,36 +141,49 @@ mergePat ctxt orig@(PRef fc n) new@(PRef _ n')
110141 return (PRef fc x)
111142 Nothing -> do put (ms { namemap = ((n', n) : namemap ms) })
112143 return (PRef fc n)
113−mergePat ctxt (PApp _ _ args) (PApp fc f args')
114− = do newArgs <- zipWithM mergeArg args args'
144+mergePat ist (PApp _ _ args) (PApp fc f args') t
145+ = do newArgs <- zipWithM mergeArg args (zip args' (argTys ist f))
115146 return (PApp fc f newArgs)
116− where mergeArg x y = do tm' <- mergePat ctxt (getTm x) (getTm y)
117− case x of
118− (PImp _ _ _ _ _ _) ->
119− return (y { machine_inf = machine_inf x,
120− getTm = tm' })
121− _ -> return (y { getTm = tm' })
122−mergePat ctxt (PRef fc n) t = do tm <- tidy t
123− addUpdate n tm
124− return tm
125−mergePat ctxt x y = return y
147+ where mergeArg x (y, t)
148+ = do tm' <- mergePat ist (getTm x) (getTm y) t
149+ case x of
150+ (PImp _ _ _ _ _ _) ->
151+ return (y { machine_inf = machine_inf x,
152+ getTm = tm' })
153+ _ -> return (y { getTm = tm' })
154+mergePat ist (PRef fc n) tm ty = do tm <- tidy ist tm ty
155+ addUpdate n tm
156+ return tm
157+mergePat ist x y t = return y
126158
127159mergeUserImpl :: PTerm -> PTerm -> PTerm
128160mergeUserImpl x y = x
129161
130−tidy orig@(PRef fc n)
162+argTys :: IState -> PTerm -> [Maybe Name]
163+argTys ist (PRef fc n)
164+ = case lookupTy n (tt_ctxt ist) of
165+ [ty] -> map (tyName . snd) (getArgTys ty) ++ repeat Nothing
166+ _ -> repeat Nothing
167+ where tyName (Bind _ (Pi _) _) = Just (UN "->")
168+ tyName t | (P _ n _, _) <- unApply t = Just n
169+ | otherwise = Nothing
170+argTys _ _ = repeat Nothing
171+
172+tidy :: IState -> PTerm -> Maybe Name -> State MergeState PTerm
173+tidy ist orig@(PRef fc n) ty
131174 = do ms <- get
132175 case lookup n (namemap ms) of
133176 Just x -> return (PRef fc x)
134177 Nothing -> case n of
135178 (UN _) -> return orig
136− _ -> return Placeholder
137−tidy (PApp fc f args)
138− = do args' <- mapM tidyArg args
179+ _ -> do n' <- inventName ist ty n
180+ return (PRef fc n')
181+tidy ist (PApp fc f args) ty
182+ = do args' <- zipWithM tidyArg args (argTys ist f)
139183 return (PApp fc f args')
140− where tidyArg x = do tm' <- tidy (getTm x)
141− return (x { getTm = tm' })
142−tidy tm = return tm
184+ where tidyArg x ty' = do tm' <- tidy ist (getTm x) ty'
185+ return (x { getTm = tm' })
186+tidy ist tm ty = return tm
143187
144188
145189-- mapPT tidyVar tm
@@ -177,17 +221,17 @@ replaceVar ctxt n t (PApp fc f pats) = PApp fc f (map substArg pats)
177221 subst (PApp fc (PRef _ t) pats)
178222 | isTConName t ctxt = Placeholder -- infer types
179223 subst (PApp fc f pats) = PApp fc f (map substArg pats)
180− subst (PEq fc l r) = PEq fc (subst l) (subst r)
224+ subst (PEq fc l r) = Placeholder -- PEq fc (subst l) (subst r)
181225 subst x = x
182226
183227 substArg arg = arg { getTm = subst (getTm arg) }
184228
185229replaceVar ctxt n t pat = pat
186230
187−splitOnLine :: Int -- ^ line number
188− -> Name -- ^ variable
189− -> FilePath -- ^ name of file
190− -> Idris [[(Name, PTerm)]]
231+splitOnLine :: Int -- ^ line number
232+ -> Name -- ^ variable
233+ -> FilePath -- ^ name of file
234+ -> Idris [[(Name, PTerm)]]
191235splitOnLine l n fn = do
192236-- let (before, later) = splitAt (l-1) (lines inp)
193237-- i <- getIState
@@ -201,7 +245,7 @@ replaceSplits :: String -> [[(Name, PTerm)]] -> Idris [String]
201245replaceSplits l ups = updateRHSs 1 (map (rep (expandBraces l)) ups)
202246 where
203247 rep str [] = str ++ "\n"
204− rep str ((n, tm) : ups) = rep (updatePat False (show n) (nshow False tm) str) ups
248+ rep str ((n, tm) : ups) = rep (updatePat False (show n) (nshow tm) str) ups
205249
206250 updateRHSs i [] = return []
207251 updateRHSs i (x : xs) = do (x', i') <- updateRHS i x
@@ -220,11 +264,10 @@ replaceSplits l ups = updateRHSs 1 (map (rep (expandBraces l)) ups)
220264
221265 -- TMP HACK: If there are Nats, we don't want to show as numerals since
222266 -- this isn't supported in a pattern, so special case here
223− nshow brack (PRef _ (UN "Z")) = "Z"
224− nshow brack (PApp _ (PRef _ (UN "S")) [x]) =
225− if brack then "(S " else "S " ++ nshow True (getTm x) ++
226− if brack then ")" else ""
227− nshow _ t = show t
267+ nshow (PRef _ (UN "Z")) = "Z"
268+ nshow (PApp _ (PRef _ (UN "S")) [x]) =
269+ "S " ++ addBrackets (nshow (getTm x))
270+ nshow t = show t
228271
229272 -- if there's any {n} replace with {n=n}
230273 expandBraces ('{' : xs)
@@ -242,9 +285,9 @@ replaceSplits l ups = updateRHSs 1 (map (rep (expandBraces l)) ups)
242285 '{' : space ++ updatePat False n tm rest'
243286 updatePat True n tm xs@(c:rest) | length xs > length n
244287 = let (before, after@(next:_)) = splitAt (length n) xs in
245− if (before == n && not (isAlpha next))
288+ if (before == n && not (isAlphaNum next))
246289 then addBrackets tm ++ updatePat False n tm after
247− else c : updatePat (not (isAlpha c)) n tm rest
290+ else c : updatePat (not (isAlphaNum c)) n tm rest
248291 updatePat start n tm (c:rest) = c : updatePat (not (isAlpha c)) n tm rest
249292
250293 addBrackets tm | ' ' `elem` tm = "(" ++ tm ++ ")"
@@ -263,25 +306,37 @@ nameRoot acc nm =
263306 (before, ('_' : after)) -> nameRoot (acc ++ [before]) after
264307 _ -> showSep "_" (acc ++ [nm])
265308
266−getClause :: Int -> -- ^ Line type is declared on
267− Name -> -- ^ Function name
268− FilePath -> -- ^ Source file name
269− Idris String
309+getClause :: Int -- ^ line number that the type is declared on
310+ -> Name -- ^ Function name
311+ -> FilePath -- ^ Source file name
312+ -> Idris String
270313getClause l fn fp = do ty <- getInternalApp fp l
271− let ap = mkApp ty [1..]
314+ ist <- get
315+ let ap = mkApp ist ty []
272316 return (show fn ++ " " ++ ap ++
273317 "= ?" ++ show fn ++ "_rhs")
274− where mkApp (PPi (Exp _ _ _ False) (MN _ _) _ sc) (n : ns)
275− = "x" ++ show n ++ " " ++ mkApp sc ns
276− mkApp (PPi (Exp _ _ _ False) n _ sc) ns
277− = show n ++ " " ++ mkApp sc ns
278− mkApp (PPi _ _ _ sc) ns = mkApp sc ns
279− mkApp _ _ = ""
280−
281−getProofClause :: Int -> -- ^ Line type is declared on
282− Name -> -- ^ Function name
283− FilePath -> -- ^ Source file name
284− Idris String
318+ where mkApp i (PPi (Exp _ _ _ False) (MN _ _) ty sc) used
319+ = let n = getNameFrom i used ty in
320+ show n ++ " " ++ mkApp i sc (n : used)
321+ mkApp i (PPi (Exp _ _ _ False) n _ sc) used
322+ = show n ++ " " ++ mkApp i sc (n : used)
323+ mkApp i (PPi _ _ _ sc) used = mkApp i sc used
324+ mkApp i _ _ = ""
325+
326+ getNameFrom i used (PPi _ _ _ _)
327+ = uniqueNameFrom (mkSupply [UN "f", UN "g"]) used
328+ getNameFrom i used (PApp fc f as) = getNameFrom i used f
329+ getNameFrom i used (PEq _ _ _) = uniqueNameFrom [UN "prf"] used
330+ getNameFrom i used (PRef fc f)
331+ = case getNameHints i f of
332+ [] -> uniqueName (UN "x") used
333+ ns -> uniqueNameFrom (mkSupply ns) used
334+ getNameFrom i used _ = uniqueName (UN "x") used
335+
336+getProofClause :: Int -- ^ line number that the type is declared
337+ -> Name -- ^ Function name
338+ -> FilePath -- ^ Source file name
339+ -> Idris String
285340getProofClause l fn fp
286341 = do ty <- getInternalApp fp l
287342 return (mkApp ty ++ " = ?" ++ show fn ++ "_rhs")
@@ -292,19 +347,34 @@ getProofClause l fn fp
292347-- match clause
293348
294349mkWith :: String -> Name -> String
295−mkWith str n = let ind = getIndent str
296− str' = replicate ind ' ' ++
297− replaceRHS str "with (_)"
298− newpat = replicate (ind + 2) ' ' ++
350+mkWith str n = let str' = replaceRHS str "with (_)"
351+ newpat = " " ++
299352 replaceRHS str "| with_pat = ?" ++ show n ++ "_rhs" in
300353 str' ++ "\n" ++ newpat
301354
302− where getIndent s = length (takeWhile isSpace s)
303−
304− replaceRHS [] str = str
355+ where replaceRHS [] str = str
305356 replaceRHS ('?':'=': rest) str = str
306357 replaceRHS ('=': rest) str
307358 | not ('=' `elem` rest) = str
308359 replaceRHS (x : rest) str = x : replaceRHS rest str
309360
361+-- Replace _ with names in missing clauses
362+
363+nameMissing :: [PTerm] -> Idris [PTerm]
364+nameMissing ps = do ist <- get
365+ newPats <- mapM nm ps
366+ let newPats' = mergeAllPats ist (UN "_") (base (head ps))
367+ newPats
368+ return (map fst newPats')
369+ where
370+ base (PApp fc f args) = PApp fc f (map (fmap (const (PRef fc (UN "_")))) args)
371+ base t = t
372+
373+ nm ptm = do mptm <- elabNewPat ptm
374+ case mptm of
375+ Nothing -> return ptm
376+ Just ptm' -> return ptm'
377+
378+
379+
310380
src/Idris/Completion.hs+1
@@ -38,6 +38,7 @@ tacticArgs = [ ("intro", Nothing) -- FIXME syntax for intro (fresh name)
3838 , ("let", Nothing) -- FIXME syntax for let
3939 , ("focus", Just ExprTArg)
4040 , ("exact", Just ExprTArg)
41+ , ("equiv", Just ExprTArg)
4142 , ("applyTactic", Just ExprTArg)
4243 , ("reflect", Just ExprTArg)
4344 , ("fill", Just ExprTArg)
src/Idris/Core/Elaborate.hs+5−2
@@ -305,6 +305,9 @@ expandLet n v = processTactic' (ExpandLet n v)
305305rewrite :: Raw -> Elab' aux ()
306306rewrite tm = processTactic' (Rewrite tm)
307307
308+induction :: Name -> Elab' aux ()
309+induction nm = processTactic' (Induction nm)
310+
308311equiv :: Raw -> Elab' aux ()
309312equiv tm = processTactic' (Equiv tm)
310313
@@ -392,7 +395,7 @@ prepare_apply fn imps =
392395 = do ctxt <- get_context
393396 case lookupTy n ctxt of
394397 [] -> lift $ tfail $ NoSuchVariable n
395− _ -> fail $ "Too many arguments for " ++ show fn
398+ _ -> lift $ tfail $ TooManyArguments n
396399 | otherwise = fail $ "Too many arguments for " ++ show fn
397400
398401 doClaim ((i, _), n, t) = do claim n t
@@ -419,7 +422,6 @@ apply' fillt fn imps =
419422 do args <- prepare_apply fn (map fst imps)
420423 env <- get_env
421424 g <- goal
422− fillt (raw_apply fn (map Var args))
423425 -- _Don't_ solve the arguments we're specifying by hand.
424426 -- (remove from unified list before calling end_unify)
425427 -- HMMM: Actually, if we get it wrong, the typechecker will complain!
@@ -439,6 +441,7 @@ apply' fillt fn imps =
439441 keepGiven dont hunis hs
440442 put (ES (p { dontunify = dont, unified = (n, unify),
441443 notunified = notunify ++ notunified p }, a) s prev)
444+ fillt (raw_apply fn (map Var args))
442445 ptm <- get_term
443446 g <- goal
444447-- trace ("Goal " ++ show g ++ "\n" ++ show (fn, imps, unify) ++ "\n" ++ show ptm) $
src/Idris/Core/Evaluate.hs+1−8
@@ -632,13 +632,6 @@ instance Show Def where
632632 show ns' ++ " " ++ show sc' ++ "\n\n" ++
633633 if inlc then "Inlinable\n" else "Not inlinable\n"
634634
635−-- We need this for serialising Def. Fortunately, it never gets used because
636−-- we'll never serialise a primitive operator
637−
638−instance Binary (a -> b) where
639− put x = return ()
640− get = error "Getting a function"
641−
642635-------
643636
644637-- Frozen => doesn't reduce
@@ -767,7 +760,7 @@ addCasedef n ci@(CaseInfo alwaysInline tcdict)
767760 OK (CaseDef args_ct sc_ct _),
768761 OK (CaseDef args_inl sc_inl _),
769762 OK (CaseDef args_rt sc_rt _)) ->
770− let inl = alwaysInline -- || tcdict
763+ let inl = alwaysInline -- tcdict
771764 inlc = (inl || small n args_ct sc_ct) && (not asserted)
772765 inlr = inl || small n args_rt sc_rt
773766 cdef = CaseDefs (args_tot, sc_tot)
src/Idris/Core/ProofState.hs+57−20
@@ -69,6 +69,7 @@ data Tactic = Attack
6969 | LetBind Name Raw Raw
7070 | ExpandLet Name Term
7171 | Rewrite Raw
72+ | Induction Name
7273 | Equiv Raw
7374 | PatVar Name
7475 | PatBind Name
@@ -566,28 +567,63 @@ rewrite tm ctxt env (Bind x (Hole t) xp@(P _ x' _)) | x == x' =
566567 (scv, sct) <- lift $ check ctxt env sc
567568 return scv
568569 _ -> fail "Not an equality type"
569− where
570− -- to make the P for rewrite, replace syntactic occurrences of l in ty with
571− -- an x, and put \x : lt in front
572− mkP lt l r ty | l == ty = lt
573− mkP lt l r (App f a) = let f' = if (r /= f) then mkP lt l r f else f
574− a' = if (r /= a) then mkP lt l r a else a in
575− App f' a'
576− mkP lt l r (Bind n b sc)
577− = let b' = mkPB b
578− sc' = if (r /= sc) then mkP lt l r sc else sc in
579− Bind n b' sc'
580− where mkPB (Let t v) = let t' = if (r /= t) then mkP lt l r t else t
581− v' = if (r /= v) then mkP lt l r v else v in
582− Let t' v'
583− mkPB b = let ty = binderTy b
584− ty' = if (r /= ty) then mkP lt l r ty else ty in
585− b { binderTy = ty' }
586− mkP lt l r x = x
587−
588− rname = MN 0 "replaced"
570+ where rname = MN 0 "replaced"
589571rewrite _ _ _ _ = fail "Can't rewrite here"
590572
573+-- To make the P for rewrite, replace syntactic occurrences of l in ty with
574+-- an x, and put \x : lt in front
575+mkP :: TT Name -> TT Name -> TT Name -> TT Name -> TT Name
576+mkP lt l r ty | l == ty = lt
577+mkP lt l r (App f a) = let f' = if (r /= f) then mkP lt l r f else f
578+ a' = if (r /= a) then mkP lt l r a else a in
579+ App f' a'
580+mkP lt l r (Bind n b sc)
581+ = let b' = mkPB b
582+ sc' = if (r /= sc) then mkP lt l r sc else sc in
583+ Bind n b' sc'
584+ where mkPB (Let t v) = let t' = if (r /= t) then mkP lt l r t else t
585+ v' = if (r /= v) then mkP lt l r v else v in
586+ Let t' v'
587+ mkPB b = let ty = binderTy b
588+ ty' = if (r /= ty) then mkP lt l r ty else ty in
589+ b { binderTy = ty' }
590+mkP lt l r x = x
591+
592+induction :: Name -> RunTactic
593+induction nm ctxt env (Bind x (Hole t) (P _ x' _)) | x == x' = do
594+ (tmv, tmt) <- lift $ check ctxt env (Var nm)
595+ let tmt' = normalise ctxt env tmt
596+ case unApply tmt' of
597+ (P _ tnm _, pms@[]) -> do
598+ case lookupTy (SN (ElimN tnm)) ctxt of
599+ [elimTy] -> do
600+ let args = getArgTys elimTy
601+ let pmargs = take (length pms) args -- TODO: Fill these correctly when having multiple parameters working
602+ let args' = drop (length pms) args
603+ let propTy = head args'
604+ let consargs = init $ tail args -- TODO: This is incorrect when type has indicies, get indicies and use the correct count
605+ let scr = last $ tail args
606+ let prop = Bind nm (Lam tmt') t -- TODO: Make this work for types with indicies
607+ let res = substV prop $ bindConsArgs consargs (mkApp (P Ref (SN (ElimN tnm)) (TType (UVal 0))) ([prop] ++ map makeConsArg consargs ++ [tmv]))
608+ action (\ps -> ps {holes = holes ps \\ [x]})
609+ mapM_ addConsHole (reverse consargs)
610+ let res' = forget $ res
611+ (scv, sct) <- lift $ check ctxt env res'
612+ let scv' = specialise ctxt env [] scv
613+ return scv'
614+ [] -> fail $ "Induction needs an eliminator for " ++ show nm
615+ xs -> fail $ "Multiple definitions found when searching for the eliminator of " ++ show nm
616+ (P _ nm _, _) -> fail "Induction not yet supported for types with arguments"
617+ _ -> fail "Unkown type for induction"
618+ where scname = MN 0 "scarg"
619+ makeConsArg (nm, ty) = P Bound nm ty
620+ bindConsArgs ((nm, ty):args) v = Bind nm (Hole ty) $ bindConsArgs args v
621+ bindConsArgs [] v = v
622+ addConsHole (nm, ty) =
623+ action (\ps -> ps { holes = nm : holes ps })
624+induction tm ctxt env _ = do fail "Can't do induction here"
625+
626+
591627equiv :: Raw -> RunTactic
592628equiv tm ctxt env (Bind x (Hole t) sc) =
593629 do (tmv, tmt) <- lift $ check ctxt env tm
@@ -819,6 +855,7 @@ process t h = tactic (Just h) (mktac t)
819855 mktac (LetBind n t v) = letbind n t v
820856 mktac (ExpandLet n b) = expandLet n b
821857 mktac (Rewrite t) = rewrite t
858+ mktac (Induction t) = induction t
822859 mktac (Equiv t) = equiv t
823860 mktac (PatVar n) = patvar n
824861 mktac (PatBind n) = patbind n
src/Idris/Core/TT.hs+15−6
@@ -85,6 +85,7 @@ data Err = Msg String
8585 | UnifyScope Name Name Term [(Name, Type)]
8686 | CantInferType String
8787 | NonFunctionType Term Term
88+ | TooManyArguments Name
8889 | CantIntroduce Term
8990 | NoSuchVariable Name
9091 | NoTypeDecl Name
@@ -237,6 +238,7 @@ data SpecialName = WhereN Int Name Name
237238 | ParentN Name String
238239 | MethodN Name
239240 | CaseN Name
241+ | ElimN Name
240242 deriving (Eq, Ord)
241243{-!
242244deriving instance Binary SpecialName
@@ -269,19 +271,21 @@ instance Show SpecialName where
269271 show (MethodN m) = "method " ++ show m
270272 show (ParentN p c) = show p ++ "#" ++ c
271273 show (CaseN n) = "case block in " ++ show n
274+ show (ElimN n) = "<<" ++ show n ++ " eliminator>>"
272275
273276-- Show a name in a way decorated for code generation, not human reading
274277showCG :: Name -> String
275278showCG (UN n) = n
276−showCG (NS n s) = showSep "." (reverse s) ++ "." ++ show n
279+showCG (NS n s) = showSep "." (reverse s) ++ "." ++ showCG n
277280showCG (MN _ "underscore") = "_"
278281showCG (MN i s) = "{" ++ s ++ show i ++ "}"
279282showCG (SN s) = showCG' s
280− where showCG' (WhereN i p c) = show p ++ ":" ++ show c ++ ":" ++ show i
281− showCG' (InstanceN cl inst) = '@':show cl ++ '$':showSep ":" inst
282− showCG' (MethodN m) = '!':show m
283− showCG' (ParentN p c) = show p ++ "#" ++ show c
284− showCG' (CaseN c) = show c ++ "_case"
283+ where showCG' (WhereN i p c) = showCG p ++ ":" ++ showCG c ++ ":" ++ show i
284+ showCG' (InstanceN cl inst) = '@':showCG cl ++ '$':showSep ":" inst
285+ showCG' (MethodN m) = '!':showCG m
286+ showCG' (ParentN p c) = showCG p ++ "#" ++ show c
287+ showCG' (CaseN c) = showCG c ++ "_case"
288+ showCG' (ElimN sn) = showCG sn ++ "_elim"
285289showCG NErased = "_"
286290
287291
@@ -831,6 +835,11 @@ getRetTy (Bind n (PVTy _) sc) = getRetTy sc
831835getRetTy (Bind n (Pi _) sc) = getRetTy sc
832836getRetTy sc = sc
833837
838+uniqueNameFrom :: [Name] -> [Name] -> Name
839+uniqueNameFrom (s : supply) hs
840+ | s `elem` hs = uniqueNameFrom supply hs
841+ | otherwise = s
842+
834843uniqueName :: Name -> [Name] -> Name
835844uniqueName n hs | n `elem` hs = uniqueName (nextName n) hs
836845 | otherwise = n
src/Idris/Coverage.hs−4
@@ -198,10 +198,6 @@ genAll i args
198198 = PPair fc (getTm l) (getTm r)
199199 resugar t = t
200200
201− getForceable i n = case lookupCtxt n (idris_optimisation i) of
202− [o] -> forceable o
203− _ -> []
204−
205201 dropForce force (x : xs) i | i `elem` force
206202 = upd Placeholder x : dropForce force xs (i + 1)
207203 dropForce force (x : xs) i = x : dropForce force xs (i + 1)
src/Idris/DataOpts.hs+160−158
@@ -5,78 +5,118 @@ module Idris.DataOpts where
55-- Forcing, detagging and collapsing
66
77import Idris.AbsSyntax
8+import Idris.AbsSyntaxTree
89import Idris.Core.TT
910
11+import Control.Applicative
12+import qualified Data.IntMap as M
1013import Data.List
1114import Data.Maybe
1215import Debug.Trace
1316
14−-- Calculate the forceable arguments to a constructor and update the set of
15−-- optimisations
16−
17−forceArgs :: Name -> Type -> Idris ()
18−forceArgs n t = do i <- getIState
19− let fargs = force i 0 t
20− copt <- case lookupCtxt n (idris_optimisation i) of
21− [] -> return $ Optimise False False [] []
22− (op:_) -> return op
23− let opts = addDef n (copt { forceable = fargs }) (idris_optimisation i)
24− putIState (i { idris_optimisation = opts })
25− addIBC (IBCOpt n)
26− iLOG $ "Forced: " ++ show n ++ " " ++ show fargs ++ "\n from " ++
27− show t
17+type ForceMap = M.IntMap Forceability
18+
19+-- Calculate the forceable arguments to a constructor
20+-- and update the set of optimisations.
21+forceArgs :: Name -> Name -> Type -> Idris ()
22+forceArgs typeName n t = do
23+ ist <- getIState
24+ let fargs = getForcedArgs ist typeName t
25+ copt = case lookupCtxt n (idris_optimisation ist) of
26+ [] -> Optimise False False [] []
27+ op:_ -> op
28+ opts = addDef n (copt { forceable = M.toList fargs }) (idris_optimisation ist)
29+ putIState (ist { idris_optimisation = opts })
30+ addIBC (IBCOpt n)
31+ iLOG $ "Forced: " ++ show n ++ " " ++ show fargs ++ "\n from " ++ show t
32+
33+getForcedArgs :: IState -> Name -> Type -> ForceMap
34+getForcedArgs ist typeName t = addCollapsibleArgs 0 t $ forcedInTarget 0 t
2835 where
29− force :: IState -> Int -> Term -> [Int]
30− force ist i (Bind _ (Pi ty) sc)
31− | collapsibleIn ist ty
32− = nub $ i : (force ist (i + 1) $ instantiate (P Bound (MN i "?") Erased) sc)
33− | otherwise = force ist (i + 1) $ instantiate (P Bound (MN i "?") Erased) sc
34− force _ _ sc@(App f a)
35− | (_, args) <- unApply sc
36− = nub $ concatMap guarded args
37− force _ _ _ = []
38−
39− collapsibleIn i t
40− | (P _ tn _, _) <- unApply t
41− = case lookupCtxt tn (idris_optimisation i) of
42− [oi] -> collapsible oi
43− _ -> False
44− | otherwise = False
45−
46− isF (P _ (MN force "?") _) = Just force
47− isF _ = Nothing
48−
49− guarded :: Term -> [Int]
50− guarded t@(App f a)
51−-- | (P (TCon _ _) _ _, args) <- unApply t
52−-- = mapMaybe isF args ++ concatMap guarded args
53− | (P (DCon _ _) _ _, args) <- unApply t
54− = mapMaybe isF args ++ concatMap guarded args
55− guarded t = mapMaybe isF [t]
36+ maxUnion = M.unionWith max
5637
57−-- Calculate whether a collection of constructors is collapsible
38+ -- Label all occurrences of the variable bound in Pi in the rest of
39+ -- the term with the number i so that we can recognize them anytime later.
40+ label i = instantiate $ P Bound (MN i "ctor_arg") Erased
41+
42+ addCollapsibleArgs :: Int -> Type -> ForceMap -> ForceMap
43+ addCollapsibleArgs i (Bind vn (Pi ty) rest) alreadyForceable
44+ = addCollapsibleArgs (i+1) (label i rest) (forceable $ unApply ty)
45+ where
46+ -- forceable takes an un-applied type of a ctor argument
47+ forceable (P _ tn _, args)
48+ -- if `ty' is collapsible, the argument is unconditionally forceable
49+ | isCollapsible tn
50+ = M.insert i Unconditional alreadyForceable
51+
52+ -- a recursive occurrence with known indices is conditionally forceable
53+ | tn == typeName
54+ = M.insertWith max i Conditional alreadyForceable
55+
56+ forceable _ = alreadyForceable
57+
58+ isCollapsible :: Name -> Bool
59+ isCollapsible n = case lookupCtxt n (idris_optimisation ist) of
60+ [oi] -> collapsible oi
61+ _ -> False
62+
63+ addCollapsibleArgs _ _ fs = fs
5864
65+ forcedInTarget :: Int -> Type -> ForceMap
66+ forcedInTarget i (Bind _ (Pi _) rest) = forcedInTarget (i+1) (label i rest)
67+ forcedInTarget i t@(App f a) | (_, as) <- unApply t = unionMap guardedArgs as
68+ forcedInTarget _ _ = M.empty
69+
70+ guardedArgs :: Term -> ForceMap
71+ guardedArgs t@(App f a) | (P (DCon _ _) _ _, args) <- unApply t
72+ = unionMap bareArg args `maxUnion` unionMap guardedArgs args
73+ guardedArgs t = bareArg t
74+
75+ bareArg :: Term -> ForceMap
76+ bareArg (P _ (MN i "ctor_arg") _) = M.singleton i Unconditional
77+ bareArg _ = M.empty
78+
79+ unionMap :: (a -> ForceMap) -> [a] -> ForceMap
80+ unionMap f = M.unionsWith max . map f
81+
82+-- Calculate whether a collection of constructors is collapsible
83+-- and update the state accordingly.
5984collapseCons :: Name -> [(Name, Type)] -> Idris ()
60−collapseCons ty cons =
61− do i <- getIState
62− let cons' = map (\ (n, t) -> (n, map snd (getArgTys t))) cons
63− allFR <- mapM (forceRec i) cons'
64− if and allFR then detaggable (map getRetTy (map snd cons))
65− else checkNewType cons'
85+collapseCons tn ctors = do
86+ ist <- getIState
87+ case ctors of
88+ _
89+ | all (ctorCollapsible ist) ctors
90+ , disjointTerms ctorTargetArgs
91+ -> mapM_ setCollapsible (tn : map fst ctors)
92+
93+ [(cn, ct)]
94+ -> checkNewType ist cn ct
95+
96+ _ -> return () -- nothing can be done
6697 where
98+ ctorTargetArgs = map (snd . unApply . getRetTy . snd) ctors
99+
100+ ctorArity :: Type -> Int
101+ ctorArity = length . getArgTys
102+
103+ ctorCollapsible :: IState -> (Name, Type) -> Bool
104+ ctorCollapsible ist (n, t) = all (`M.member` forceMap) [0 .. ctorArity t - 1]
105+ where
106+ forceMap = case lookupCtxt n (idris_optimisation ist) of
107+ oi:_ -> M.fromList $ forceable oi
108+ _ -> M.empty
109+
67110 -- one constructor; if one remaining argument, treat as newtype
68− checkNewType [(n, ts)] = do
69− i <- getIState
70− case lookupCtxt n (idris_optimisation i) of
71− (oi:_) -> do let remaining = length ts - length (forceable oi)
72− if remaining == 1 then
73− do let oi' = oi { isnewtype = True }
74− let opts = addDef n oi' (idris_optimisation i)
75− putIState (i { idris_optimisation = opts })
76− else return ()
77− _ -> return ()
78−
79− checkNewType _ = return ()
111+ checkNewType :: IState -> Name -> Type -> Idris ()
112+ checkNewType ist cn ct
113+ | oi:_ <- lookupCtxt cn opt
114+ , length (getArgTys ct) == 1 + forcedCnt (M.fromList $ forceable oi)
115+ = putIState ist{ idris_optimisation = opt' oi }
116+ | otherwise = return ()
117+ where
118+ opt = idris_optimisation ist
119+ opt' oi = addDef cn oi{ isnewtype = True } opt
80120
81121 setCollapsible :: Name -> Idris ()
82122 setCollapsible n
@@ -91,79 +131,49 @@ collapseCons ty cons =
91131 putIState (i { idris_optimisation = opts })
92132 addIBC (IBCOpt n)
93133
94− forceRec :: IState -> (Name, [Type]) -> Idris Bool
95− forceRec i (n, ts)
96− = case lookupCtxt n (idris_optimisation i) of
97− (oi:_) -> checkFR (forceable oi) 0 ts
98− _ -> return False
99− checkFR fs i [] = return True
100− checkFR fs i (_ : xs) | i `elem` fs = checkFR fs (i + 1) xs
101− checkFR fs i (t : xs)
102− -- must be recursive or type is not collapsible
103− = do let (rtf, rta) = unApply $ getRetTy t
104− if (ty `elem` freeNames rtf)
105− then checkFR fs (i+1) xs
106− else return False
107−
108− detaggable :: [Type] -> Idris ()
109− detaggable rtys
110− = do let rtyArgs = map (snd . unApply) rtys
111− -- if every rtyArgs is disjoint with every other, it's detaggable,
112− -- therefore also collapsible given forceable/recursive check
113− if disjoint rtyArgs
114− then mapM_ setCollapsible (ty : map fst cons)
115− else return ()
116−
117− disjoint :: [[Term]] -> Bool
118− disjoint [] = True
119− disjoint [x] = True
120− disjoint (x : xs) = anyDisjoint x xs && disjoint xs
121−
122− anyDisjoint x [] = True
123− anyDisjoint x (y : ys) = disjointCons x y
124−
125− disjointCons [] [] = False
126− disjointCons [] y = False
127− disjointCons x [] = False
128− disjointCons (x : xs) (y : ys)
129− = disjointCon x y || disjointCons xs ys
130−
131− disjointCon x y = let (cx, _) = unApply x
132− (cy, _) = unApply y in
133− case (cx, cy) of
134− (P (DCon _ _) nx _, P (DCon _ _) ny _) -> nx /= ny
135− _ -> False
134+ disjointTerms :: [[Term]] -> Bool
135+ disjointTerms [] = True
136+ disjointTerms [xs] = True
137+ disjointTerms (xs : xss) =
138+ -- xs is disjoint with every pattern from xss
139+ all (or . zipWith disjoint xs) xss
140+ -- and xss is pairwise disjoint, too
141+ && disjointTerms xss
142+
143+ -- Return True if the two patterns are provably disjoint.
144+ -- Return False if they're not or if unsure.
145+ disjoint :: Term -> Term -> Bool
146+ disjoint x y = case (cx, cy) of
147+ -- data constructors -> compare their names
148+ (P (DCon _ _) nx _, P (DCon _ _) ny _)
149+ | nx /= ny -> True
150+ | otherwise -> or $ zipWith disjoint xargs yargs
151+ _ -> False
152+ where
153+ (cx, xargs) = unApply x
154+ (cy, yargs) = unApply y
136155
137156class Optimisable term where
138157 applyOpts :: term -> Idris term
139158 stripCollapsed :: term -> Idris term
140159
141160instance (Optimisable a, Optimisable b) => Optimisable (a, b) where
142− applyOpts (x, y) = do x' <- applyOpts x
143− y' <- applyOpts y
144− return (x', y')
145− stripCollapsed (x, y) = do x' <- stripCollapsed x
146− y' <- stripCollapsed y
147− return (x', y')
148−
161+ applyOpts (x, y) = (,) <$> applyOpts x <*> applyOpts y
162+ stripCollapsed (x, y) = (,) <$> stripCollapsed x <*> stripCollapsed y
149163
150164instance (Optimisable a, Optimisable b) => Optimisable (vs, a, b) where
151− applyOpts (v, x, y) = do x' <- applyOpts x
152− y' <- applyOpts y
153− return (v, x', y')
154− stripCollapsed (v, x, y) = do x' <- stripCollapsed x
155− y' <- stripCollapsed y
156− return (v, x', y')
165+ applyOpts (v, x, y) = (,,) v <$> applyOpts x <*> applyOpts y
166+ stripCollapsed (v, x, y) = (,,) v <$> stripCollapsed x <*> stripCollapsed y
157167
158168instance Optimisable a => Optimisable [a] where
159169 applyOpts = mapM applyOpts
160170 stripCollapsed = mapM stripCollapsed
161171
162172instance Optimisable a => Optimisable (Either a (a, a)) where
163− applyOpts (Left t) = do t' <- applyOpts t; return $ Left t'
164− applyOpts (Right t) = do t' <- applyOpts t; return $ Right t'
165− stripCollapsed (Left t) = do t' <- stripCollapsed t; return $ Left t'
166− stripCollapsed (Right t) = do t' <- stripCollapsed t; return $ Right t'
173+ applyOpts (Left t) = Left <$> applyOpts t
174+ applyOpts (Right t) = Right <$> applyOpts t
175+ stripCollapsed (Left t) = Left <$> stripCollapsed t
176+ stripCollapsed (Right t) = Right <$> stripCollapsed t
167177
168178-- Raw is for compile time optimisation (before type checking)
169179-- Term is for run time optimisation (after type checking, collapsing allowed)
@@ -175,41 +185,39 @@ instance Optimisable Raw where
175185 | (Var n, args) <- raw_unapply t -- MAGIC HERE
176186 = do args' <- mapM applyOpts args
177187 i <- getIState
178− case lookupCtxt n (idris_optimisation i) of
179− (oi:_) -> return $ applyDataOpt oi n args'
180− _ -> return (raw_apply (Var n) args')
181− | otherwise = do f' <- applyOpts f
182− a' <- applyOpts a
183− return (RApp f' a')
184− applyOpts (RBind n b t) = do b' <- applyOpts b
185− t' <- applyOpts t
186− return (RBind n b' t')
187− applyOpts (RForce t) = applyOpts t
188+ return $ case lookupCtxt n (idris_optimisation i) of
189+ oi:_ -> applyDataOpt oi n args'
190+ _ -> raw_apply (Var n) args'
191+ | otherwise = RApp <$> applyOpts f <*> applyOpts a
192+
193+ applyOpts (RBind n b t) = RBind n <$> applyOpts b <*> applyOpts t
194+ applyOpts (RForce t) = applyOpts t
188195 applyOpts t = return t
189196
190197 stripCollapsed t = return t
191198
192199instance Optimisable t => Optimisable (Binder t) where
193− applyOpts (Let t v) = do t' <- applyOpts t
194− v' <- applyOpts v
195− return (Let t' v')
200+ applyOpts (Let t v) = Let <$> applyOpts t <*> applyOpts v
196201 applyOpts b = do t' <- applyOpts (binderTy b)
197202 return (b { binderTy = t' })
198− stripCollapsed (Let t v) = do t' <- stripCollapsed t
199− v' <- stripCollapsed v
200− return (Let t' v')
203+ stripCollapsed (Let t v) = Let <$> stripCollapsed t <*> stripCollapsed v
201204 stripCollapsed b = do t' <- stripCollapsed (binderTy b)
202205 return (b { binderTy = t' })
203206
207+forcedArgSeq :: OptInfo -> [Maybe Forceability]
208+forcedArgSeq oi = map (\i -> M.lookup i forceMap) [0..]
209+ where
210+ forceMap = M.fromList $ forceable oi
211+
212+forcedCnt :: ForceMap -> Int
213+forcedCnt = length . filter (== Unconditional) . M.elems
204214
205215applyDataOpt :: OptInfo -> Name -> [Raw] -> Raw
206−applyDataOpt oi n args
207− = let args' = zipWith doForce (map (\x -> x `elem` (forceable oi)) [0..])
208− args in
209− raw_apply (Var n) args'
216+applyDataOpt oi n args
217+ = raw_apply (Var n) $ zipWith doForce (forcedArgSeq oi) args
210218 where
211− doForce True a = RForce a
212− doForce False a = a
219+ doForce (Just Unconditional) a = RForce a
220+ doForce _ a = a
213221
214222-- Run-time: do everything
215223
@@ -268,10 +276,10 @@ instance Optimisable (TT Name) where
268276
269277applyDataOptRT :: OptInfo -> Name -> Int -> Int -> [Term] -> Term
270278applyDataOptRT oi n tag arity args
271− | length args == arity = doOpts n args (collapsible oi) (forceable oi)
279+ | length args == arity = doOpts n args (collapsible oi) (M.fromList $ forceable oi)
272280 | otherwise = let extra = satArgs (arity - length args)
273281 tm = doOpts n (args ++ map (\n -> P Bound n Erased) extra)
274− (collapsible oi) (forceable oi) in
282+ (collapsible oi) (M.fromList $ forceable oi) in
275283 bind extra tm
276284 where
277285 satArgs n = map (\i -> MN i "sat") [1..n]
@@ -285,18 +293,12 @@ applyDataOptRT oi n tag arity args
285293 doOpts (NS (UN "S") ["Nat", "Prelude"]) [k] _ _
286294 = App (App (P Ref (UN "prim__addBigInt") Erased) k) (Constant (BI 1))
287295
288− doOpts n args True f = Erased
289− doOpts n args _ forced
290− = let args' = filter keep (zip (map (\x -> x `elem` forced) [0..])
291− args) in
292− if isnewtype oi
293− then case args' of
294− [(_, val)] -> val
295− _ -> error "Can't happen (not isnewtype)"
296− else
297− mkApp (P (DCon tag (arity - length forced)) n Erased)
298− (map snd args')
299−
300− keep (forced, _) = not forced
301−
302−
296+ doOpts n args True _ = Erased
297+ doOpts n args _ forceMap
298+ | isnewtype oi = case args' of
299+ [val] -> val
300+ _ -> error $ "Can't happen (newtype not a singleton): " ++ show args'
301+ | otherwise = mkApp ctor' args'
302+ where
303+ ctor' = (P (DCon tag (arity - forcedCnt forceMap)) n Erased)
304+ args' = [t | (f, t) <- zip (forcedArgSeq oi) args, f /= Just Unconditional]
src/Idris/DeepSeq.hs+13−2
@@ -2,11 +2,16 @@ module Idris.DeepSeq where
22
33import Idris.Core.TT
44import Idris.AbsSyntax
5+import Idris.AbsSyntaxTree
56
67import Control.DeepSeq
78
89-- All generated by 'derive'
910
11+instance NFData Forceability where
12+ rnf Conditional = ()
13+ rnf Unconditional = ()
14+
1015instance NFData Raw where
1116 rnf (Var x1) = rnf x1 `seq` ()
1217 rnf (RBind x1 x2 x3) = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` ()
@@ -31,6 +36,7 @@ instance NFData SpecialName where
3136 rnf (ParentN x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
3237 rnf (MethodN x1) = rnf x1 `seq` ()
3338 rnf (CaseN x1) = rnf x1 `seq` ()
39+ rnf (ElimN x1) = rnf x1 `seq` ()
3440
3541instance NFData IntTy where
3642 rnf (ITFixed x1) = rnf x1 `seq` ()
@@ -164,6 +170,10 @@ instance NFData FnOpt where
164170 rnf Reflection = ()
165171 rnf (Specialise x1) = rnf x1 `seq` ()
166172
173+instance NFData DataOpt where
174+ rnf Codata = ()
175+ rnf DefaultEliminator = ()
176+
167177instance (NFData t) => NFData (PDecl' t) where
168178 rnf (PFix x1 x2 x3) = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` ()
169179 rnf (PTy x1 x2 x3 x4 x5 x6)
@@ -271,6 +281,7 @@ instance (NFData t) => NFData (PTactic' t) where
271281 rnf (Focus x1) = rnf x1 `seq` ()
272282 rnf (Refine x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
273283 rnf (Rewrite x1) = rnf x1 `seq` ()
284+ rnf (Induction x1) = rnf x1 `seq` ()
274285 rnf (Equiv x1) = rnf x1 `seq` ()
275286 rnf (MatchRefine x1) = rnf x1 `seq` ()
276287 rnf (LetTac x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
@@ -315,9 +326,9 @@ instance (NFData t) => NFData (PArg' t) where
315326 rnf x2 `seq` rnf x3 `seq` rnf x4 `seq` rnf x5 `seq` rnf x6 `seq` ()
316327
317328instance NFData ClassInfo where
318− rnf (CI x1 x2 x3 x4 x5)
329+ rnf (CI x1 x2 x3 x4 x5 x6)
319330 = rnf x1 `seq`
320− rnf x2 `seq` rnf x3 `seq` rnf x4 `seq` rnf x5 `seq` ()
331+ rnf x2 `seq` rnf x3 `seq` rnf x4 `seq` rnf x5 `seq` rnf x6 `seq` ()
321332
322333instance NFData OptInfo where
323334 rnf (Optimise x1 x2 x3 x4)
src/Idris/Delaborate.hs+2
@@ -154,6 +154,8 @@ pshow i (NonFunctionType f ty)
154154 let colour = idris_colourRepl i in
155155 showImp (Just i) imps colour (delab i f) ++ " does not have a function type ("
156156 ++ showImp (Just i) imps colour (delab i ty) ++ ")"
157+pshow i (TooManyArguments f)
158+ = "Too many arguments for " ++ show f
157159pshow i (CantIntroduce ty)
158160 = let imps = opt_showimp (idris_options i) in
159161 let colour = idris_colourRepl i in
src/Idris/ElabDecls.hs+354−34
@@ -33,6 +33,12 @@ import Data.List
3333import Data.Maybe
3434import Debug.Trace
3535
36+import qualified Data.Map as Map
37+import Data.Char(isLetter, toLower)
38+import Data.List.Split (splitOn)
39+
40+import Util.Pretty(pretty)
41+
3642recheckC fc env t
3743 = do -- t' <- applyOpts (forget t) (doesn't work, or speed things up...)
3844 ctxt <- getContext
@@ -143,9 +149,10 @@ elabPostulate info syn doc fc opts n ty
143149 -- remove it from the deferred definitions list
144150 solveDeferred n
145151
146−elabData :: ElabInfo -> SyntaxInfo -> String -> FC -> Bool -> PData -> Idris ()
147−elabData info syn doc fc codata (PLaterdecl n t_in)
148− = do iLOG (show (fc, doc))
152+elabData :: ElabInfo -> SyntaxInfo -> String -> FC -> DataOpts -> PData -> Idris ()
153+elabData info syn doc fc opts (PLaterdecl n t_in)
154+ = do let codata = Codata `elem` opts
155+ iLOG (show (fc, doc))
149156 checkUndefined fc n
150157 ctxt <- getContext
151158 i <- getIState
@@ -161,8 +168,9 @@ elabData info syn doc fc codata (PLaterdecl n t_in)
161168 logLvl 2 $ "---> " ++ show cty
162169 updateContext (addTyDecl n (TCon 0 0) cty) -- temporary, to check cons
163170
164−elabData info syn doc fc codata (PDatadecl n t_in dcons)
165− = do iLOG (show fc)
171+elabData info syn doc fc opts (PDatadecl n t_in dcons)
172+ = do let codata = Codata `elem` opts
173+ iLOG (show fc)
166174 undef <- isUndefined fc n
167175 ctxt <- getContext
168176 i <- getIState
@@ -173,6 +181,9 @@ elabData info syn doc fc codata (PDatadecl n t_in dcons)
173181 (errAt "data declaration " n (erun fc (build i info False n t)))
174182 def' <- checkDef fc defer
175183 let def'' = map (\(n, (i, top, t)) -> (n, (i, top, t, True))) def'
184+ -- if n is defined already, make sure it is just a type declaration
185+ -- with the same type we've just elaborated
186+ checkDefinedAs fc n t' (tt_ctxt i)
176187 addDeferredTyCon def''
177188 mapM_ (elabCaseBlock info []) is
178189 (cty, _) <- recheckC fc [] t'
@@ -194,7 +205,17 @@ elabData info syn doc fc codata (PDatadecl n t_in dcons)
194205 collapseCons n cons
195206 updateContext (addDatatype (Data n ttag cty cons))
196207 mapM_ (checkPositive n) cons
208+ if DefaultEliminator `elem` opts then evalStateT (elabEliminator params n t dcons info) Map.empty
209+ else return ()
197210 where
211+ checkDefinedAs fc n t ctxt
212+ = case lookupDef n ctxt of
213+ [] -> return ()
214+ [TyDecl _ ty] ->
215+ case converts ctxt [] t ty of
216+ OK () -> return ()
217+ _ -> tclift $ tfail (At fc (AlreadyDefined n))
218+ _ -> tclift $ tfail (At fc (AlreadyDefined n))
198219 -- parameters are names which are unchanged across the structure,
199220 -- which appear exactly once in the return type of a constructor
200221
@@ -245,12 +266,253 @@ elabData info syn doc fc codata (PDatadecl n t_in dcons)
245266 | otherwise = count n ts
246267 mParam args (_ : rest) = Nothing : mParam args rest
247268
269+type EliminatorState = StateT (Map.Map String Int) Idris
270+
271+-- TODO: Use uniqueName for generating names, rewrite everything to use idris_implicits instead of manual splitting, generally just rewrite
272+elabEliminator :: [Int] -> Name -> PTerm -> [(String, Name, PTerm, FC)] -> ElabInfo -> EliminatorState ()
273+elabEliminator paramPos n ty cons info = do
274+ elimLog $ "Elaborating eliminator"
275+ let (cnstrs, _) = splitPi ty
276+ let (splittedTy@(pms, idxs)) = splitPms cnstrs
277+ generalParams <- namePis False pms
278+ motiveIdxs <- namePis False idxs
279+ let motive = mkMotive n paramPos generalParams motiveIdxs
280+ consTerms <- mapM (\(c@(_,cnm,_,_)) -> do
281+ name <- freshName $ "elim_" ++ simpleName cnm
282+ consTerm <- extractConsTerm c generalParams
283+ return (name, expl, consTerm)) cons
284+ scrutineeIdxs <- namePis False idxs
285+ let motiveConstr = [(motiveName, expl, motive)]
286+ let scrutinee = (scrutineeName, expl, applyCons n (interlievePos paramPos generalParams scrutineeIdxs 0))
287+ let eliminatorTy = piConstr (generalParams ++ motiveConstr ++ consTerms ++ scrutineeIdxs ++ [scrutinee]) (applyMotive (map (\(n,_,_) -> PRef elimFC n) scrutineeIdxs) (PRef elimFC scrutineeName))
288+ let eliminatorTyDecl = PTy (show n) defaultSyntax elimFC [TotalFn] elimDeclName eliminatorTy
289+ let clauseConsElimArgs = map getPiName consTerms
290+ let clauseGeneralArgs' = map getPiName generalParams ++ [motiveName] ++ clauseConsElimArgs
291+ let clauseGeneralArgs = map (\arg -> pexp (PRef elimFC arg)) clauseGeneralArgs'
292+ let elimSig = "-- eliminator signature: " ++ showImp Nothing True True eliminatorTy
293+ eliminatorClauses <- mapM (\(cns, cnsElim) -> generateEliminatorClauses cns cnsElim clauseGeneralArgs generalParams) (zip cons clauseConsElimArgs)
294+ let eliminatorDef = PClauses emptyFC [TotalFn] elimDeclName eliminatorClauses
295+ elimLog $ "-- eliminator definition: " ++ showDeclImp True eliminatorDef
296+ Control.Monad.State.lift $ idrisCatch (elabDecl EAll info eliminatorTyDecl) (\err -> return ())
297+ -- Do not elaborate clauses if there aren't any
298+ case eliminatorClauses of
299+ [] -> return ()
300+ _ -> Control.Monad.State.lift $ idrisCatch (elabDecl EAll info eliminatorDef) (\err -> return ())
301+ where elimLog :: String -> EliminatorState ()
302+ elimLog s = Control.Monad.State.lift (logLvl 2 s)
303+
304+ elimFC :: FC
305+ elimFC = fileFC "(eliminator)"
306+
307+ elimDeclName :: Name
308+ elimDeclName = SN $ ElimN n
309+
310+ applyNS :: Name -> [String] -> Name
311+ applyNS n [] = n
312+ applyNS n ns = NS n ns
313+
314+ splitPi :: PTerm -> ([(Name, Plicity, PTerm)], PTerm)
315+ splitPi = splitPi' []
316+ where splitPi' :: [(Name, Plicity, PTerm)] -> PTerm -> ([(Name, Plicity, PTerm)], PTerm)
317+ splitPi' acc (PPi pl n tyl tyr) = splitPi' ((n, pl, tyl):acc) tyr
318+ splitPi' acc t = (reverse acc, t)
319+
320+ splitPms :: [(Name, Plicity, PTerm)] -> ([(Name, Plicity, PTerm)], [(Name, Plicity, PTerm)])
321+ splitPms cnstrs = (map fst pms, map fst idxs)
322+ where (pms, idxs) = partition (\c -> snd c `elem` paramPos) (zip cnstrs [0..])
323+
324+ isMachineGenerated :: Name -> Bool
325+ isMachineGenerated (MN _ _) = True
326+ isMachineGenerated _ = False
327+
328+ namePis :: Bool -> [(Name, Plicity, PTerm)] -> EliminatorState [(Name, Plicity, PTerm)]
329+ namePis keepOld pms = do names <- mapM (mkPiName keepOld) pms
330+ let oldNames = map fst names
331+ let params = map snd names
332+ return $ map (\(n, pl, ty) -> (n, pl, removeParamPis oldNames params ty)) params
333+
334+ mkPiName :: Bool -> (Name, Plicity, PTerm) -> EliminatorState (Name, (Name, Plicity, PTerm))
335+ mkPiName keepOld (n, pl, piarg) | not (isMachineGenerated n) && keepOld = do return (n, (n, pl, piarg))
336+ mkPiName _ (oldName, pl, piarg) = do name <- freshName $ keyOf piarg
337+ return (oldName, (name, pl, piarg))
338+ where keyOf :: PTerm -> String
339+ keyOf (PRef _ name) | isLetter (nameStart name) = (toLower $ nameStart name):"__"
340+ keyOf (PApp _ tyf _) = keyOf tyf
341+ keyOf PType = "ty__"
342+ keyOf _ = "carg__"
343+ nameStart :: Name -> Char
344+ nameStart n = nameStart' (simpleName n)
345+ where nameStart' :: String -> Char
346+ nameStart' "" = ' '
347+ nameStart' ns = head ns
348+
349+ simpleName :: Name -> String
350+ simpleName (NS n _) = simpleName n
351+ simpleName (MN i n) = n ++ show i
352+ simpleName n = show n
353+
354+ nameSpaces :: Name -> [String]
355+ nameSpaces (NS _ ns) = ns
356+ nameSpaces _ = []
357+
358+ freshName :: String -> EliminatorState Name
359+ freshName key = do
360+ nameMap <- get
361+ let i = fromMaybe 0 (Map.lookup key nameMap)
362+ let name = key ++ show i
363+ put $ Map.insert key (i+1) nameMap
364+ return (UN name)
365+
366+ scrutineeName :: Name
367+ scrutineeName = UN "scrutinee"
368+
369+ scrutineeArgName :: Name
370+ scrutineeArgName = UN "scrutineeArg"
371+
372+ motiveName :: Name
373+ motiveName = UN "prop"
374+
375+ mkMotive :: Name -> [Int] -> [(Name, Plicity, PTerm)] -> [(Name, Plicity, PTerm)] -> PTerm
376+ mkMotive n paramPos params indicies =
377+ let scrutineeTy = (scrutineeArgName, expl, applyCons n (interlievePos paramPos params indicies 0))
378+ in piConstr (indicies ++ [scrutineeTy]) PType
379+
380+ piConstr :: [(Name, Plicity, PTerm)] -> PTerm -> PTerm
381+ piConstr [] ty = ty
382+ piConstr ((n, pl, tyb):tyr) ty = PPi pl n tyb (piConstr tyr ty)
383+
384+ interlievePos :: [Int] -> [a] -> [a] -> Int -> [a]
385+ interlievePos idxs [] l2 i = l2
386+ interlievePos idxs l1 [] i = l1
387+ interlievePos idxs (x:xs) l2 i | i `elem` idxs = x:(interlievePos idxs xs l2 (i+1))
388+ interlievePos idxs l1 (y:ys) i = y:(interlievePos idxs l1 ys (i+1))
389+
390+ replaceParams :: [Int] -> [(Name, Plicity, PTerm)] -> PTerm -> PTerm
391+ replaceParams paramPos params cns =
392+ let (_, cnsResTy) = splitPi cns
393+ in case cnsResTy of
394+ PApp _ _ args ->
395+ let oldParams = paramNamesOf 0 paramPos args
396+ in removeParamPis oldParams params cns
397+ _ -> cns
398+
399+ removeParamPis :: [Name] -> [(Name, Plicity, PTerm)] -> PTerm -> PTerm
400+ removeParamPis oldParams params (PPi pl n tyb tyr) =
401+ case findIndex (== n) oldParams of
402+ Nothing -> (PPi pl n (removeParamPis oldParams params tyb) (removeParamPis oldParams params tyr))
403+ Just i -> (removeParamPis oldParams params tyr)
404+ removeParamPis oldParams params (PRef _ n) =
405+ case findIndex (== n) oldParams of
406+ Nothing -> (PRef elimFC n)
407+ Just i -> let (newname,_,_) = params !! i in (PRef elimFC (newname))
408+ removeParamPis oldParams params (PApp _ cns args) =
409+ PApp elimFC (removeParamPis oldParams params cns) $ replaceParamArgs args
410+ where replaceParamArgs :: [PArg] -> [PArg]
411+ replaceParamArgs [] = []
412+ replaceParamArgs (arg:args) =
413+ case extractName (getTm arg) of
414+ [] -> arg:replaceParamArgs args
415+ [n] ->
416+ case findIndex (== n) oldParams of
417+ Nothing -> arg:replaceParamArgs args
418+ Just i -> let (newname,_,_) = params !! i in arg {getTm = PRef elimFC newname}:replaceParamArgs args
419+ removeParamPis oldParams params t = t
420+
421+ paramNamesOf :: Int -> [Int] -> [PArg] -> [Name]
422+ paramNamesOf i paramPos [] = []
423+ paramNamesOf i paramPos (arg:args) = (if i `elem` paramPos then extractName (getTm arg) else []) ++ paramNamesOf (i+1) paramPos args
424+
425+ extractName :: PTerm -> [Name]
426+ extractName (PRef _ n) = [n]
427+ extractName _ = []
428+
429+ splitArgPms :: PTerm -> ([PTerm], [PTerm])
430+ splitArgPms (PApp _ f args) = splitArgPms' args
431+ where splitArgPms' :: [PArg] -> ([PTerm], [PTerm])
432+ splitArgPms' cnstrs = (map (getTm . fst) pms, map (getTm . fst) idxs)
433+ where (pms, idxs) = partition (\c -> snd c `elem` paramPos) (zip cnstrs [0..])
434+ splitArgPms _ = ([],[])
435+
436+
437+ implicitIndexes :: (String, Name, PTerm, FC) -> EliminatorState [(Name, Plicity, PTerm)]
438+ implicitIndexes (cns@(doc, cnm, ty, fc)) = do
439+ i <- Control.Monad.State.lift getIState
440+ implargs' <- case lookupCtxt cnm (idris_implicits i) of
441+ [] -> do fail $ "Error while showing implicits for " ++ show cnm
442+ [args] -> do return args
443+ _ -> do fail $ "Ambigous name for " ++ show cnm
444+ let implargs = mapMaybe convertImplPi implargs'
445+ let (_, cnsResTy) = splitPi ty
446+ case cnsResTy of
447+ PApp _ _ args ->
448+ let oldParams = paramNamesOf 0 paramPos args
449+ in return $ filter (\(n,_,_) -> not (n `elem` oldParams))implargs
450+ _ -> return implargs
451+
452+ extractConsTerm :: (String, Name, PTerm, FC) -> [(Name, Plicity, PTerm)] -> EliminatorState PTerm
453+ extractConsTerm (doc, cnm, ty, fc) generalParameters = do
454+ let cons' = replaceParams paramPos generalParameters ty
455+ let (args, resTy) = splitPi cons'
456+ implidxs <- implicitIndexes (doc, cnm, ty, fc)
457+ consArgs <- namePis True args
458+ let recArgs = findRecArgs consArgs
459+ let recMotives = map applyRecMotive recArgs
460+ let (_, consIdxs) = splitArgPms resTy
461+ return $ piConstr (implidxs ++ consArgs ++ recMotives) (applyMotive consIdxs (applyCons cnm consArgs))
462+ where applyRecMotive :: (Name, Plicity, PTerm) -> (Name, Plicity, PTerm)
463+ applyRecMotive (n,_,ty) = (UN $ "ih" ++ simpleName n, expl, applyMotive idxs (PRef elimFC n))
464+ where (_, idxs) = splitArgPms ty
465+
466+ findRecArgs :: [(Name, Plicity, PTerm)] -> [(Name, Plicity, PTerm)]
467+ findRecArgs [] = []
468+ findRecArgs (ty@(_,_,PRef _ tn):rs) | simpleName tn == simpleName n = ty:findRecArgs rs
469+ findRecArgs (ty@(_,_,PApp _ (PRef _ tn) _):rs) | simpleName tn == simpleName n = ty:findRecArgs rs
470+ findRecArgs (ty:rs) = findRecArgs rs
471+
472+ applyCons :: Name -> [(Name, Plicity, PTerm)] -> PTerm
473+ applyCons tn targs = PApp elimFC (PRef elimFC tn) (map convertArg targs)
474+
475+ convertArg :: (Name, Plicity, PTerm) -> PArg
476+ convertArg (n, _, _) = pexp (PRef elimFC n)
477+
478+ applyMotive :: [PTerm] -> PTerm -> PTerm
479+ applyMotive idxs t = PApp elimFC (PRef elimFC motiveName) (map pexp idxs ++ [pexp t])
480+
481+ getPiName :: (Name, Plicity, PTerm) -> Name
482+ getPiName (name,_,_) = name
483+
484+ convertImplPi :: PArg -> Maybe (Name, Plicity, PTerm)
485+ convertImplPi (PImp {getTm = t, pname = n}) = Just (n, expl, t)
486+ convertImplPi _ = Nothing
487+
488+ generateEliminatorClauses :: (String, Name, PTerm, FC) -> Name -> [PArg] -> [(Name, Plicity, PTerm)] -> EliminatorState PClause
489+ generateEliminatorClauses (doc, cnm, ty, fc) cnsElim generalArgs generalParameters = do
490+ let cons' = replaceParams paramPos generalParameters ty
491+ let (args, resTy) = splitPi cons'
492+ i <- Control.Monad.State.lift getIState
493+ implidxs <- implicitIndexes (doc, cnm, ty, fc)
494+ let (_, generalIdxs') = splitArgPms resTy
495+ let generalIdxs = map pexp generalIdxs'
496+ consArgs <- namePis True args
497+ let lhsPattern = PApp elimFC (PRef elimFC elimDeclName) (generalArgs ++ generalIdxs ++ [pexp $ applyCons cnm consArgs])
498+ let recArgs = findRecArgs consArgs
499+ let recElims = map applyRecElim recArgs
500+ let rhsExpr = PApp elimFC (PRef elimFC cnsElim) (map convertArg implidxs ++ map convertArg consArgs ++ recElims)
501+ return $ PClause elimFC elimDeclName lhsPattern [] rhsExpr []
502+ where applyRecElim :: (Name, Plicity, PTerm) -> PArg
503+ applyRecElim (constr@(recCnm,_,recTy)) = pexp $ PApp elimFC (PRef elimFC elimDeclName) (generalArgs ++ map pexp idxs ++ [pexp $ PRef elimFC recCnm])
504+ where (_, idxs) = splitArgPms recTy
505+
248506-- | Elaborate primitives
249507
250508elabPrims :: Idris ()
251509elabPrims = do mapM_ (elabDecl EAll toplevel)
252− (map (PData "" defaultSyntax (fileFC "builtin") False)
253− [inferDecl, unitDecl, falseDecl, pairDecl, eqDecl])
510+ (map (\(opt, decl) -> PData "" defaultSyntax (fileFC "builtin") opt decl)
511+ (zip
512+ [inferOpts, unitOpts, falseOpts, pairOpts, eqOpts]
513+ [inferDecl, unitDecl, falseDecl, pairDecl, eqDecl]))
514+ addNameHint eqTy (UN "prf")
515+ elabDecl EAll toplevel elimDecl
254516 mapM_ elabPrim primitives
255517 -- Special case prim__believe_me because it doesn't work on just constants
256518 elabBelieveMe
@@ -400,7 +662,7 @@ elabTransform info fc safe lhs_in rhs_in
400662elabRecord :: ElabInfo -> SyntaxInfo -> String -> FC -> Name ->
401663 PTerm -> String -> Name -> PTerm -> Idris ()
402664elabRecord info syn doc fc tyn ty cdoc cn cty
403− = do elabData info syn doc fc False (PDatadecl tyn ty [(cdoc, cn, cty, fc)])
665+ = do elabData info syn doc fc [] (PDatadecl tyn ty [(cdoc, cn, cty, fc)])
404666 cty' <- implicit syn cn cty
405667 i <- getIState
406668 cty <- case lookupTy cn (tt_ctxt i) of
@@ -531,7 +793,7 @@ elabCon info syn tn codata (doc, n, t_in, fc)
531793 addIBC (IBCDef n)
532794 addDocStr n doc
533795 addIBC (IBCDoc n)
534− forceArgs n cty'
796+ forceArgs tn n cty'
535797 return (n, cty')
536798 where
537799 tyIs (Bind n b sc) = tyIs sc
@@ -638,7 +900,7 @@ elabClauses info fc opts n_in cs = let n = liftname info n_in in
638900 Just _ -> logLvl 5 $ "Partially evaluated:\n" ++ show pats
639901 _ -> return ()
640902
641− let optpdef = map debind optpats -- $ map (simple_lhs (tt_ctxt ist)) optpats
903+ let optpdef = map debind optpats -- \$ map (simple_lhs (tt_ctxt ist)) optpats
642904 tree@(CaseDef scargs sc _) <- tclift $
643905 simpleCase tcase False reflect CompileTime fc pdef
644906 cov <- coverage
@@ -797,7 +1059,7 @@ elabPE info fc caller r =
7971059
7981060 mkSpecialised ist specapp_in = do
7991061 let (specTy, specapp) = getSpecTy ist specapp_in
800− let (n, newnm, [(lhs, rhs)]) = getSpecClause ist specapp
1062+ let (n, newnm, pats) = getSpecClause ist specapp
8011063 let undef = case lookupDef newnm (tt_ctxt ist) of
8021064 [] -> True
8031065 _ -> False
@@ -812,10 +1074,12 @@ elabPE info fc caller r =
8121074 iLOG $ "PE definition type : " ++ (show specTy)
8131075 ++ "\n" ++ show opts
8141076 logLvl 2 $ "PE definition " ++ show newnm ++ ":\n" ++
815− (showImp Nothing True False lhs ++ " = " ++
816− showImp Nothing True False rhs)
1077+ showSep "\n"
1078+ (map (\ (lhs, rhs) ->
1079+ (showImp Nothing True False lhs ++ " = " ++
1080+ showImp Nothing True False rhs)) pats)
8171081 elabType info defaultSyntax "" fc opts newnm specTy
818− let def = [PClause fc newnm lhs [] rhs []]
1082+ let def = map (\ (lhs, rhs) -> PClause fc newnm lhs [] rhs []) pats
8191083 elabClauses info fc opts newnm def
8201084 logLvl 1 $ "Specialised " ++ show newnm)
8211085 -- if it doesn't work, just don't specialise. Could happen for lots
@@ -918,7 +1182,18 @@ checkPossible info fc tcgen fname lhs_in
9181182-- b <- inferredDiff fc (delab' i lhs_tm True) lhs
9191183-- return (not b) -- then return (Just lhs_tm) else return Nothing
9201184-- trace (show (delab' i lhs_tm True) ++ "\n" ++ show lhs) $ return (not b)
921− err@(Error _) -> return False
1185+ Error err -> return (impossibleError err)
1186+ where impossibleError (CantUnify _ topx topy e _ _)
1187+ = not (sameFam topx topy || not (impossibleError e))
1188+ impossibleError (CantConvert _ _ _) = False
1189+ impossibleError (At _ e) = impossibleError e
1190+ impossibleError (Elaborating _ _ e) = impossibleError e
1191+ impossibleError _ = True
1192+
1193+ sameFam topx topy
1194+ = case (unApply topx, unApply topy) of
1195+ ((P _ x _, _), (P _ y _, _)) -> x == y
1196+ _ -> False
9221197
9231198elabClause :: ElabInfo -> FnOpts -> (Int, PClause) ->
9241199 Idris (Either Term (Term, Term))
@@ -926,7 +1201,8 @@ elabClause info opts (_, PClause fc fname lhs_in [] PImpossible [])
9261201 = do let tcgen = Dictionary `elem` opts
9271202 b <- checkPossible info fc tcgen fname lhs_in
9281203 case b of
929− True -> ifail $ show fc ++ ":" ++ show lhs_in ++ " is a possible case"
1204+ True -> tclift $ tfail (At fc
1205+ (Msg $ show lhs_in ++ " is a valid case"))
9301206 False -> do ptm <- mkPatTm lhs_in
9311207 return (Left ptm)
9321208elabClause info opts (cnum, PClause fc fname lhs_in withs rhs_in whereblock)
@@ -1268,6 +1544,8 @@ elabClass info syn doc fc constraints tn ps ds
12681544 (map (pexp . PRef fc) (map fst ps))
12691545 -- build data declaration
12701546 let mdecls = filter tydecl ds -- method declarations
1547+ let idecls = filter instdecl ds -- default superclass instance declarations
1548+ mapM_ checkDefaultSuperclassInstance idecls
12711549 let mnames = map getMName mdecls
12721550 logLvl 2 $ "Building methods " ++ show mnames
12731551 ims <- mapM (tdecl mnames) mdecls
@@ -1276,7 +1554,7 @@ elabClass info syn doc fc constraints tn ps ds
12761554 let (methods, imethods)
12771555 = unzip (map (\ ( x,y,z) -> (x, y)) ims)
12781556 let defaults = map (\ (x, (y, z)) -> (x,y)) defs
1279− addClass tn (CI cn (map nodoc imethods) defaults (map fst ps) [])
1557+ addClass tn (CI cn (map nodoc imethods) defaults idecls (map fst ps) [])
12801558 -- build instance constructor type
12811559 -- decorate names of functions to ensure they can't be referred
12821560 -- to elsewhere in the class declaration
@@ -1286,7 +1564,7 @@ elabClass info syn doc fc constraints tn ps ds
12861564 let cons = [("", cn, cty, fc)]
12871565 let ddecl = PDatadecl tn tty cons
12881566 logLvl 5 $ "Class data " ++ showDImp True ddecl
1289− elabData info (syn { no_imp = no_imp syn ++ mnames }) doc fc False ddecl
1567+ elabData info (syn { no_imp = no_imp syn ++ mnames }) doc fc [] ddecl
12901568 -- for each constraint, build a top level function to chase it
12911569 logLvl 5 $ "Building functions"
12921570 let usyn = syn { using = map (\ (x,y) -> UImplicit x y) ps
@@ -1298,7 +1576,6 @@ elabClass info syn doc fc constraints tn ps ds
12981576 mapM_ (elabDecl EAll info) (concat fns)
12991577 -- add the default definitions
13001578 mapM_ (elabDecl EAll info) (concat (map (snd.snd) defs))
1301− i <- getIState
13021579 addIBC (IBCClass tn)
13031580 where
13041581 nodoc (n, (_, o, t)) = (n, (o, t))
@@ -1309,6 +1586,17 @@ elabClass info syn doc fc constraints tn ps ds
13091586 mdec (NS x n) = NS (mdec x) n
13101587 mdec x = x
13111588
1589+ -- TODO: probably should normalise
1590+ checkDefaultSuperclassInstance (PInstance _ fc cs n ps _ _ _)
1591+ = do when (not $ null cs) . tclift
1592+ $ tfail (At fc (Msg $ "Default superclass instances can't have constraints."))
1593+ i <- getIState
1594+ let t = PApp fc (PRef fc n) (map pexp ps)
1595+ let isConstrained = any (== t) constraints
1596+ when (not isConstrained) . tclift
1597+ $ tfail (At fc (Msg $ "Default instances must be for a superclass constraint on the containing class."))
1598+ return ()
1599+
13121600 impbind [] x = x
13131601 impbind ((n, ty): ns) x = PPi impl n ty (impbind ns x)
13141602 conbind (ty : ns) x = PPi constraint (MN 0 "class") ty (conbind ns x)
@@ -1340,6 +1628,8 @@ elabClass info syn doc fc constraints tn ps ds
13401628
13411629 tydecl (PTy _ _ _ _ _ _) = True
13421630 tydecl _ = False
1631+ instdecl (PInstance _ _ _ _ _ _ _ _) = True
1632+ instdecl _ = False
13431633 clause (PClauses _ _ _ _) = True
13441634 clause _ = False
13451635
@@ -1425,15 +1715,12 @@ elabInstance info syn fc cs n ps t expn ds
14251715 [c] -> return c
14261716 _ -> ifail $ show fc ++ ":" ++ show n ++ " is not a type class"
14271717 let constraint = PApp fc (PRef fc n) (map pexp ps)
1428− let iname = case expn of
1429− Nothing -> SN (InstanceN n (map show ps))
1430− -- UN ('@':show n ++ "$" ++ show ps)
1431− Just nm -> nm
1718+ let iname = mkiname n ps expn
14321719 nty <- elabType' True info syn "" fc [] iname t
14331720 -- if the instance type matches any of the instances we have already,
14341721 -- and it's not a named instance, then it's overlapping, so report an error
14351722 case expn of
1436− Nothing -> do mapM_ (checkNotOverlapping i (delab i nty))
1723+ Nothing -> do mapM_ (maybe (return ()) overlapping . findOverlapping i (delab i nty))
14371724 (class_instances ci)
14381725 addInstance intInst n iname
14391726 Just _ -> addInstance intInst n iname
@@ -1447,6 +1734,9 @@ elabInstance info syn fc cs n ps t expn ds
14471734 PApp _ _ args -> getWParams args
14481735 _ -> return []) ps
14491736 let pnames = map pname (concat (nub wparams))
1737+ let superclassInstances = map (substInstance ips pnames) (class_default_superclasses ci)
1738+ undefinedSuperclassInstances <- filterM (fmap not . isOverlapping i) superclassInstances
1739+ mapM_ (elabDecl EAll info) undefinedSuperclassInstances
14501740 let all_meths = map (nsroot . fst) (class_methods ci)
14511741 let mtys = map (\ (n, (op, t)) ->
14521742 let t_in = substMatchesShadow ips pnames t
@@ -1473,7 +1763,7 @@ elabInstance info syn fc cs n ps t expn ds
14731763 let idecls = [PClauses fc [Dictionary] iname
14741764 [PClause fc iname lhs [] rhs wb]]
14751765 iLOG (show idecls)
1476− mapM (elabDecl EAll info) idecls
1766+ mapM_ (elabDecl EAll info) idecls
14771767 addIBC (IBCInstance intInst n iname)
14781768-- -- for each constraint, build a top level function to chase it
14791769-- logLvl 5 $ "Building functions"
@@ -1484,20 +1774,50 @@ elabInstance info syn fc cs n ps t expn ds
14841774 [PConstant (AType (ATInt ITNative))] -> True
14851775 _ -> False
14861776
1487− checkNotOverlapping i t n
1488− | take 2 (show n) == "@@" = return ()
1777+ mkiname n' ps' expn' =
1778+ case expn' of
1779+ Nothing -> SN (InstanceN n' (map show ps'))
1780+ Just nm -> nm
1781+
1782+ substInstance ips pnames (PInstance syn _ cs n ps t expn ds)
1783+ = PInstance syn fc cs n (map (substMatchesShadow ips pnames) ps) (substMatchesShadow ips pnames t) expn ds
1784+
1785+ isOverlapping i (PInstance syn _ _ n ps t expn _)
1786+ = case lookupCtxtName n (idris_classes i) of
1787+ [(n, ci)] -> let iname = (mkiname n ps expn) in
1788+ case lookupTy iname (tt_ctxt i) of
1789+ [] -> elabFindOverlapping i ci iname syn t
1790+ (_:_) -> return True
1791+ _ -> return False -- couldn't find class, just let elabInstance fail later
1792+
1793+ -- TODO: largely based upon elabType' - should try to abstract
1794+ elabFindOverlapping i ci iname syn t
1795+ = do ty' <- addUsingConstraints syn fc t
1796+ ty' <- implicit syn iname ty'
1797+ let ty = addImpl i ty'
1798+ ctxt <- getContext
1799+ ((tyT, _, _), _) <-
1800+ tclift $ elaborate ctxt iname (TType (UVal 0)) []
1801+ (errAt "type of " iname (erun fc (build i info False iname ty)))
1802+ ctxt <- getContext
1803+ (cty, _) <- recheckC fc [] tyT
1804+ let nty = normalise ctxt [] cty
1805+ return $ any (isJust . findOverlapping i (delab i nty)) (class_instances ci)
1806+
1807+ findOverlapping i t n
1808+ | take 2 (show n) == "@@" = Nothing
14891809 | otherwise
14901810 = case lookupTy n (tt_ctxt i) of
14911811 [t'] -> let tret = getRetType t
14921812 tret' = getRetType (delab i t') in
14931813 case matchClause i tret' tret of
1494− Right ms -> overlapping tret tret'
1814+ Right ms -> Just tret'
14951815 Left _ -> case matchClause i tret tret' of
1496− Right ms -> overlapping tret tret'
1497− Left _ -> return ()
1498− _ -> return ()
1499− overlapping t t' = tclift $ tfail (At fc (Msg $
1500− "Overlapping instance: " ++ show t' ++ " already defined"))
1816+ Right ms -> Just tret'
1817+ Left _ -> Nothing
1818+ _ -> Nothing
1819+ overlapping t' = tclift $ tfail (At fc (Msg $
1820+ "Overlapping instance: " ++ show t' ++ " already defined"))
15011821 getRetType (PPi _ _ _ sc) = getRetType sc
15021822 getRetType t = t
15031823
@@ -1709,7 +2029,7 @@ elabDecl' what info (PRecord doc s f tyn ty cdoc cn cty)
17092029 elabRecord info s doc f tyn ty cdoc cn cty
17102030 | otherwise
17112031 = do iLOG $ "Elaborating [type of] " ++ show tyn
1712− elabData info s doc f False (PLaterdecl tyn ty)
2032+ elabData info s doc f [] (PLaterdecl tyn ty)
17132033elabDecl' _ info (PDSL n dsl)
17142034 = do i <- getIState
17152035 putIState (i { idris_dsls = addDef n dsl (idris_dsls i) })
src/Idris/ElabTerm.hs+17−12
@@ -47,14 +47,16 @@ build ist info pattern fn tm
4747 when (not pattern) $
4848 mapM_ (\n -> when (n `elem` hs) $
4949 do focus n
50− try (resolveTC 7 fn ist)
50+ g <- goal
51+ try (resolveTC 7 g fn ist)
5152 (movelast n)) ivs
5253 ivs <- get_instances
5354 hs <- get_holes
5455 when (not pattern) $
5556 mapM_ (\n -> when (n `elem` hs) $
5657 do focus n
57− resolveTC 7 fn ist) ivs
58+ g <- goal
59+ resolveTC 7 g fn ist) ivs
5860 tm <- get_term
5961 ctxt <- get_context
6062 when (not pattern) $ do matchProblems; unifyProblems
@@ -150,12 +152,12 @@ elab ist info pattern tcgen fn tm
150152 (elab' ina (PRef fc unitTy))
151153 elab' ina (PFalse fc) = elab' ina (PRef fc falseTy)
152154 elab' ina (PResolveTC (FC "HACK" _ _)) -- for chasing parent classes
153− = resolveTC 5 fn ist
155+ = do g <- goal; resolveTC 5 g fn ist
154156 elab' ina (PResolveTC fc)
155157 | True = do c <- unique_hole (MN 0 "class")
156158 instanceArg c
157159 | otherwise = do g <- goal
158− try (resolveTC 2 fn ist)
160+ try (resolveTC 2 g fn ist)
159161 (do c <- unique_hole (MN 0 "class")
160162 instanceArg c)
161163 elab' ina (PRefl fc t)
@@ -414,7 +416,7 @@ elab ist info pattern tcgen fn tm
414416 hs <- get_holes
415417 if all (\n -> not (n `elem` hs)) (freeNames g)
416418 -- let insts = filter tcname $ map fst (ctxtAlist (tt_ctxt ist))
417− then try (resolveTC 7 fn ist)
419+ then try (resolveTC 7 g fn ist)
418420 (movelast n)
419421 else movelast n)
420422 (ivs' \\ ivs)
@@ -639,7 +641,7 @@ findInstances :: IState -> Term -> [Name]
639641findInstances ist t
640642 | (P _ n _, _) <- unApply t
641643 = case lookupCtxt n (idris_classes ist) of
642− [CI _ _ _ _ ins] -> ins
644+ [CI _ _ _ _ _ ins] -> ins
643645 _ -> []
644646 | otherwise = []
645647
@@ -649,10 +651,10 @@ proofSearch' ist top n hints
649651 = proofSearch (elab ist toplevel False False (MN 0 "tac")) top n hints ist
650652
651653
652−resolveTC :: Int -> Name -> IState -> ElabD ()
653−resolveTC 0 fn ist = fail $ "Can't resolve type class"
654−resolveTC 1 fn ist = try' (trivial' ist) (resolveTC 0 fn ist) True
655−resolveTC depth fn ist
654+resolveTC :: Int -> Term -> Name -> IState -> ElabD ()
655+resolveTC 0 topg fn ist = fail $ "Can't resolve type class"
656+resolveTC 1 topg fn ist = try' (trivial' ist) (resolveTC 0 topg fn ist) True
657+resolveTC depth topg fn ist
656658 = do hnf_compute
657659 g <- goal
658660 ptm <- get_term
@@ -701,7 +703,7 @@ resolveTC depth fn ist
701703
702704 blunderbuss t d [] = do -- c <- get_env
703705 -- ps <- get_probs
704− lift $ tfail $ CantResolve t
706+ lift $ tfail $ CantResolve topg
705707 blunderbuss t d (n:ns)
706708 | n /= fn && tcname n = try' (resolve n d)
707709 (blunderbuss t d ns) True
@@ -729,7 +731,7 @@ resolveTC depth fn ist
729731 t' <- goal
730732 let (tc', ttype) = unApply t'
731733 let depth' = if t == t' then depth - 1 else depth
732− resolveTC depth' fn ist)
734+ resolveTC depth' topg fn ist)
733735 (filter (\ (x, y) -> not x) (zip (map fst imps) args))
734736 -- if there's any arguments left, we've failed to resolve
735737 hs <- get_holes
@@ -838,6 +840,9 @@ runTac autoSolve ist tac
838840 elab ist toplevel False False (MN 0 "tac") tm
839841 rewrite (Var letn)
840842 when autoSolve solveAll
843+ runT (Induction nm)
844+ = do induction nm
845+ when autoSolve solveAll
841846 runT (LetTac n tm)
842847 = do attack
843848 tyn <- unique_hole (MN 0 "letty")
src/Idris/IBC.hs+52−16
@@ -23,7 +23,7 @@ import Debug.Trace
2323import Paths_idris
2424
2525ibcVersion :: Word8
26−ibcVersion = 44
26+ibcVersion = 48
2727
2828data IBCFile = IBCFile { ver :: Word8,
2929 sourcefile :: FilePath,
@@ -51,7 +51,8 @@ data IBCFile = IBCFile { ver :: Word8,
5151 ibc_docstrings :: [(Name, String)],
5252 ibc_transforms :: [(Term, Term)],
5353 ibc_coercions :: [Name],
54− ibc_lineapps :: [(FilePath, Int, PTerm)]
54+ ibc_lineapps :: [(FilePath, Int, PTerm)],
55+ ibc_namehints :: [(Name, Name)]
5556 }
5657 deriving Show
5758{-!
@@ -59,7 +60,7 @@ deriving instance Binary IBCFile
5960!-}
6061
6162initIBC :: IBCFile
62−initIBC = IBCFile ibcVersion "" [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] []
63+initIBC = IBCFile ibcVersion "" [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] []
6364
6465loadIBC :: FilePath -> Idris ()
6566loadIBC fp = do iLOG $ "Loading ibc " ++ fp
@@ -137,6 +138,8 @@ ibc i (IBCTotal n a) f = return f { ibc_total = (n,a) : ibc_total f }
137138ibc i (IBCTrans t) f = return f { ibc_transforms = t : ibc_transforms f }
138139ibc i (IBCLineApp fp l t) f
139140 = return f { ibc_lineapps = (fp,l,t) : ibc_lineapps f }
141+ibc i (IBCNameHint (n, ty)) f
142+ = return f { ibc_namehints = (n, ty) : ibc_namehints f }
140143
141144process :: IBCFile -> FilePath -> Idris ()
142145process i fn
@@ -172,6 +175,7 @@ process i fn
172175 pCoercions (ibc_coercions i)
173176 pTrans (ibc_transforms i)
174177 pLineApps (ibc_lineapps i)
178+ pNameHints (ibc_namehints i)
175179
176180timestampOlder :: FilePath -> FilePath -> IO ()
177181timestampOlder src ibc = do srct <- getModificationTime src
@@ -221,7 +225,7 @@ pClasses cs = mapM_ (\ (n, c) ->
221225 -- Don't lose instances from previous IBCs, which
222226 -- could have loaded in any order
223227 let is = case lookupCtxt n (idris_classes i) of
224− [CI _ _ _ _ ins] -> ins
228+ [CI _ _ _ _ _ ins] -> ins
225229 _ -> []
226230 let c' = c { class_instances =
227231 class_instances c ++ is }
@@ -319,6 +323,9 @@ pTrans ts = mapM_ addTrans ts
319323pLineApps :: [(FilePath, Int, PTerm)] -> Idris ()
320324pLineApps ls = mapM_ (\ (f, i, t) -> addInternalApp f i t) ls
321325
326+pNameHints :: [(Name, Name)] -> Idris ()
327+pNameHints ns = mapM_ (\ (n, ty) -> addNameHint n ty) ns
328+
322329----- Generated by 'derive'
323330
324331instance Binary SizeChange where
@@ -410,6 +417,7 @@ instance Binary SpecialName where
410417 MethodN x1 -> do putWord8 3
411418 put x1
412419 CaseN x1 -> do putWord8 4; put x1
420+ ElimN x1 -> do putWord8 5; put x1
413421 get
414422 = do i <- getWord8
415423 case i of
@@ -427,6 +435,8 @@ instance Binary SpecialName where
427435 return (MethodN x1)
428436 4 -> do x1 <- get
429437 return (CaseN x1)
438+ 5 -> do x1 <- get
439+ return (ElimN x1)
430440 _ -> error "Corrupted binary data for SpecialName"
431441
432442
@@ -797,10 +807,7 @@ instance Binary Def where
797807 1 -> do x1 <- get
798808 x2 <- get
799809 return (TyDecl x1 x2)
800− 2 -> do x1 <- get
801− x2 <- get
802− x3 <- get
803− return (Operator x1 x2 x3)
810+ -- Operator isn't written, don't read
804811 3 -> do x1 <- get
805812 x2 <- get
806813 x3 <- get
@@ -823,6 +830,20 @@ instance Binary Accessibility where
823830 2 -> return Hidden
824831 _ -> error "Corrupted binary data for Accessibility"
825832
833+safeToEnum :: (Enum a, Bounded a, Integral int) => String -> int -> a
834+safeToEnum label x' = result
835+ where
836+ x = fromIntegral x'
837+ result
838+ | x < fromEnum (minBound `asTypeOf` result)
839+ || x > fromEnum (maxBound `asTypeOf` result)
840+ = error $ label ++ ": corrupted binary representation in IBC"
841+ | otherwise = toEnum x
842+
843+instance Binary Forceability where
844+ put = putWord8 . fromIntegral . fromEnum
845+ get = safeToEnum "Forceability" `fmap` getWord8
846+
826847instance Binary PReason where
827848 put x
828849 = case x of
@@ -870,7 +891,7 @@ instance Binary Totality where
870891 _ -> error "Corrupted binary data for Totality"
871892
872893instance Binary IBCFile where
873− put x@(IBCFile x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27)
894+ put x@(IBCFile x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28)
874895 = {-# SCC "putIBCFile" #-}
875896 do put x1
876897 put x2
@@ -899,6 +920,7 @@ instance Binary IBCFile where
899920 put x25
900921 put x26
901922 put x27
923+ put x28
902924 get
903925 = do x1 <- get
904926 if x1 == ibcVersion then
@@ -928,9 +950,19 @@ instance Binary IBCFile where
928950 x25 <- get
929951 x26 <- get
930952 x27 <- get
931− return (IBCFile x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27)
953+ x28 <- get
954+ return (IBCFile x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28)
932955 else return (initIBC { ver = x1 })
933956
957+instance Binary DataOpt where
958+ put x = case x of
959+ Codata -> putWord8 0
960+ DefaultEliminator -> putWord8 1
961+ get = do i <- getWord8
962+ case i of
963+ 0 -> return Codata
964+ 1 -> return DefaultEliminator
965+
934966instance Binary FnOpt where
935967 put x
936968 = case x of
@@ -1225,7 +1257,7 @@ instance Binary Using where
12251257 1 -> do x1 <- get; x2 <- get; return (UConstraint x1 x2)
12261258
12271259instance Binary SyntaxInfo where
1228− put (Syn x1 x2 x3 x4 x5 x6 x7 x8)
1260+ put (Syn x1 x2 x3 x4 _ x5 x6 x7)
12291261 = do put x1
12301262 put x2
12311263 put x3
@@ -1233,7 +1265,6 @@ instance Binary SyntaxInfo where
12331265 put x5
12341266 put x6
12351267 put x7
1236− put x8
12371268 get
12381269 = do x1 <- get
12391270 x2 <- get
@@ -1242,8 +1273,7 @@ instance Binary SyntaxInfo where
12421273 x5 <- get
12431274 x6 <- get
12441275 x7 <- get
1245− x8 <- get
1246− return (Syn x1 x2 x3 x4 x5 x6 x7 x8)
1276+ return (Syn x1 x2 x3 x4 id x5 x6 x7)
12471277
12481278instance (Binary t) => Binary (PClause' t) where
12491279 put x
@@ -1576,6 +1606,8 @@ instance (Binary t) => Binary (PTactic' t) where
15761606 put x1
15771607 Fill x1 -> do putWord8 18
15781608 put x1
1609+ Induction x1 -> do putWord8 19
1610+ put x1
15791611 get
15801612 = do i <- getWord8
15811613 case i of
@@ -1613,6 +1645,8 @@ instance (Binary t) => Binary (PTactic' t) where
16131645 return (Reflect x1)
16141646 18 -> do x1 <- get
16151647 return (Fill x1)
1648+ 19 -> do x1 <- get
1649+ return (Induction x1)
16161650 _ -> error "Corrupted binary data for PTactic'"
16171651
16181652
@@ -1727,17 +1761,19 @@ instance (Binary t) => Binary (PArg' t) where
17271761
17281762
17291763instance Binary ClassInfo where
1730− put (CI x1 x2 x3 x4 _)
1764+ put (CI x1 x2 x3 x4 x5 _)
17311765 = do put x1
17321766 put x2
17331767 put x3
17341768 put x4
1769+ put x5
17351770 get
17361771 = do x1 <- get
17371772 x2 <- get
17381773 x3 <- get
17391774 x4 <- get
1740− return (CI x1 x2 x3 x4 [])
1775+ x5 <- get
1776+ return (CI x1 x2 x3 x4 x5 [])
17411777
17421778instance Binary OptInfo where
17431779 put (Optimise x1 x2 x3 x4)
src/Idris/IdeSlave.hs+3
@@ -66,6 +66,9 @@ instance (SExpable a, SExpable b) => SExpable (a, b) where
6666instance (SExpable a, SExpable b, SExpable c) => SExpable (a, b, c) where
6767 toSExp (l, m, n) = SexpList [toSExp l, toSExp m, toSExp n]
6868
69+instance (SExpable a, SExpable b, SExpable c, SExpable d) => SExpable (a, b, c, d) where
70+ toSExp (l, m, n, o) = SexpList [toSExp l, toSExp m, toSExp n, toSExp o]
71+
6972escape :: String -> String
7073escape = concatMap escapeChar
7174 where
src/Idris/ParseData.hs+23−13
@@ -70,13 +70,19 @@ record syn = do (doc, acc) <- try (do
7070{- | Parses data declaration type (normal or codata)
7171DataI ::= 'data' | 'codata';
7272-}
73−dataI :: IdrisParser Bool
74−dataI = do reserved "data"; return False
75− <|> do reserved "codata"; return True
73+dataI :: IdrisParser DataOpts
74+dataI = do reserved "data"; return []
75+ <|> do reserved "codata"; return [Codata]
76+
77+{- | Parses if a data should not have a default eliminator
78+DefaultEliminator ::= 'noelim'?
79+ -}
80+defaultEliminator :: IdrisParser DataOpts
81+defaultEliminator = do option [] (do reserved "%elim"; return [DefaultEliminator])
7682
7783{- | Parses a data type declaration
78−Data ::= DocComment? Accessibility? DataI FnName TypeSig ExplicitTypeDataRest?
79− | DocComment? Accessibility? DataI FnName Name* DataRest?
84+Data ::= DocComment? Accessibility? DataI DefaultEliminator FnName TypeSig ExplicitTypeDataRest?
85+ | DocComment? Accessibility? DataI DefaultEliminator FnName Name* DataRest?
8086 ;
8187Constructor' ::= Constructor KeepTerminator;
8288ExplicitTypeDataRest ::= 'where' OpenBlock Constructor'* CloseBlock;
@@ -90,29 +96,31 @@ SimpleConstructorList ::=
9096 ;
9197-}
9298data_ :: SyntaxInfo -> IdrisParser PDecl
93−data_ syn = do (doc, acc, co) <- try (do
99+data_ syn = do (doc, acc, dataOpts) <- try (do
94100 doc <- option "" (docComment '|')
95101 pushIndent
96102 acc <- optional accessibility
103+ elim <- defaultEliminator
97104 co <- dataI
98− return (doc, acc, co))
105+ let dataOpts = combineDataOpts(elim ++ co)
106+ return (doc, acc, dataOpts))
99107 fc <- getFC
100108 tyn_in <- fnName
101109 (do try (lchar ':')
102110 popIndent
103111 ty <- typeExpr (allowImp syn)
104112 let tyn = expandNS syn tyn_in
105− option (PData doc syn fc co (PLaterdecl tyn ty)) (do
113+ option (PData doc syn fc dataOpts (PLaterdecl tyn ty)) (do
106114 reserved "where"
107115 cons <- indentedBlock (constructor syn)
108116 accData acc tyn (map (\ (_, n, _, _) -> n) cons)
109− return $ PData doc syn fc co (PDatadecl tyn ty cons))) <|> (do
117+ return $ PData doc syn fc dataOpts (PDatadecl tyn ty cons))) <|> (do
110118 args <- many name
111119 let ty = bindArgs (map (const PType) args) PType
112120 let tyn = expandNS syn tyn_in
113− option (PData doc syn fc co (PLaterdecl tyn ty)) (do
121+ option (PData doc syn fc dataOpts (PLaterdecl tyn ty)) (do
114122 try (lchar '=') <|> do reserved "where"
115− let kw = (if co then "co" else "") ++ "data "
123+ let kw = (if DefaultEliminator `elem` dataOpts then "" else "%noelim ") ++ (if Codata `elem` dataOpts then "co" else "") ++ "data "
116124 let n = show tyn_in ++ " "
117125 let s = kw ++ n
118126 let as = concat (intersperse " " $ map show args) ++ " "
@@ -129,14 +137,16 @@ data_ syn = do (doc, acc, co) <- try (do
129137 do let cty = bindArgs cargs conty
130138 return (doc, x, cty, cfc)) cons
131139 accData acc tyn (map (\ (_, n, _, _) -> n) cons')
132− return $ PData doc syn fc co (PDatadecl tyn ty cons')))
140+ return $ PData doc syn fc dataOpts (PDatadecl tyn ty cons')))
133141 <?> "data type declaration"
134142 where
135143 mkPApp :: FC -> PTerm -> [PTerm] -> PTerm
136144 mkPApp fc t [] = t
137145 mkPApp fc t xs = PApp fc t (map pexp xs)
138146 bindArgs :: [PTerm] -> PTerm -> PTerm
139− bindArgs xs t = foldr (PPi expl (MN 0 "t")) t xs
147+ bindArgs xs t = foldr (PPi expl (MN 0 "_t")) t xs
148+ combineDataOpts :: DataOpts -> DataOpts
149+ combineDataOpts opts = if Codata `elem` opts then delete DefaultEliminator opts else opts
140150
141151
142152{- | Parses a type constructor declaration
src/Idris/ParseExpr.hs+127−37
@@ -42,8 +42,10 @@ allowImp syn = syn { implicitAllowed = True }
4242disallowImp :: SyntaxInfo -> SyntaxInfo
4343disallowImp syn = syn { implicitAllowed = False }
4444
45−{- | Parses an expression as a whole
45+{-| Parses an expression as a whole
46+@
4647 FullExpr ::= Expr EOF_t;
48+@
4749 -}
4850fullExpr :: SyntaxInfo -> IdrisParser PTerm
4951fullExpr syn = do x <- expr syn
@@ -53,7 +55,9 @@ fullExpr syn = do x <- expr syn
5355
5456
5557{- |Parses an expression
58+@
5659 Expr ::= Expr';
60+@
5761-}
5862expr :: SyntaxInfo -> IdrisParser PTerm
5963expr syn = do i <- get
@@ -61,10 +65,10 @@ expr syn = do i <- get
6165
6266{- | Parses either an internally defined expression or
6367 a user-defined one
64−
68+@
6569Expr' ::= "External (User-defined) Syntax"
6670 | InternalExpr;
67−
71+@
6872 -}
6973expr' :: SyntaxInfo -> IdrisParser PTerm
7074expr' syn = try (externalExpr syn)
@@ -92,7 +96,7 @@ simpleExternalExpr syn = do i <- get
9296 _ -> False
9397 isSimple _ = False
9498
95−{- | Tries to parse a user-defined expression given a list of syntactic extensions -}
99+{- | Tries to parse a user-defined expression given a list of syntactic extensions -}
96100extensions :: SyntaxInfo -> [Syntax] -> IdrisParser PTerm
97101extensions syn rules = choice (map (try . extension syn) (filter isValid rules))
98102 <?> "user-defined expression"
@@ -160,8 +164,8 @@ extension syn (Rule ssym ptm _)
160164 update ns (PGoal fc r n sc) = PGoal fc (update ns r) n (update ns sc)
161165 update ns t = t
162166
163−{- |Parses a (normal) built-in expression
164−
167+{- | Parses a (normal) built-in expression
168+@
165169InternalExpr ::=
166170 App
167171 | MatchApp
@@ -173,8 +177,9 @@ InternalExpr ::=
173177 | Let
174178 | RewriteTerm
175179 | Pi
176− | DoBlock
180+ | DoBlock
177181 ;
182+@
178183-}
179184internalExpr :: SyntaxInfo -> IdrisParser PTerm
180185internalExpr syn =
@@ -193,8 +198,10 @@ internalExpr syn =
193198 <?> "expression"
194199
195200{- | Parses a case expression
201+@
196202CaseExpr ::=
197203 'case' Expr 'of' OpenBlock CaseOption+ CloseBlock;
204+@
198205-}
199206caseExpr :: SyntaxInfo -> IdrisParser PTerm
200207caseExpr syn = do reserved "case"; fc <- getFC
@@ -204,9 +211,11 @@ caseExpr syn = do reserved "case"; fc <- getFC
204211 <?> "case expression"
205212
206213{- | Parses a case in a case expression
214+@
207215CaseOption ::=
208216 Expr '=>' Expr Terminator
209217 ;
218+@
210219-}
211220caseOption :: SyntaxInfo -> IdrisParser (PTerm, PTerm)
212221caseOption syn = do lhs <- expr (syn { inPattern = True })
@@ -215,9 +224,11 @@ caseOption syn = do lhs <- expr (syn { inPattern = True })
215224 <?> "case option"
216225
217226{- | Parses a proof block
227+@
218228ProofExpr ::=
219229 'proof' OpenBlock Tactic'* CloseBlock
220230 ;
231+@
221232-}
222233proofExpr :: SyntaxInfo -> IdrisParser PTerm
223234proofExpr syn = do reserved "proof"
@@ -225,10 +236,12 @@ proofExpr syn = do reserved "proof"
225236 return $ PProof ts
226237 <?> "proof block"
227238
228−{- | Parses a tactics block
239+{- | Parses a tactics block
240+@
229241TacticsExpr :=
230242 'tactics' OpenBlock Tactic'* CloseBlock
231243;
244+@
232245-}
233246tacticsExpr :: SyntaxInfo -> IdrisParser PTerm
234247tacticsExpr syn = do reserved "tactics"
@@ -236,7 +249,8 @@ tacticsExpr syn = do reserved "tactics"
236249 return $ PTactics ts
237250 <?> "tactics block"
238251
239−{- | Parses a simple expresion
252+{- | Parses a simple expression
253+@
240254SimpleExpr ::=
241255 '![' Term ']'
242256 | '?' Name
@@ -257,6 +271,7 @@ SimpleExpr ::=
257271 | '_'
258272 | {- External (User-defined) Simple Expression -}
259273 ;
274+@
260275-}
261276simpleExpr :: SyntaxInfo -> IdrisParser PTerm
262277simpleExpr syn =
@@ -267,6 +282,7 @@ simpleExpr syn =
267282 tm <- option Placeholder (do lchar '{'; t <- expr syn; lchar '}';
268283 return t)
269284 return (PRefl fc tm)
285+ <|> do reserved "elim_for"; fc <- getFC; t <- fnName; return (PRef fc (SN $ ElimN t))
270286 <|> proofExpr syn
271287 <|> tacticsExpr syn
272288 <|> caseExpr syn
@@ -295,7 +311,8 @@ simpleExpr syn =
295311 <?> "expression"
296312
297313
298−{- |Parses the rest of an expression in braces
314+{- |Parses the rest of an expression in braces
315+@
299316Bracketed ::=
300317 ')'
301318 | Expr ')'
@@ -305,6 +322,7 @@ Bracketed ::=
305322 | Expr Operator ')'
306323 | Name ':' Expr '**' Expr ')'
307324 ;
325+@
308326-}
309327bracketed :: SyntaxInfo -> IdrisParser PTerm
310328bracketed syn =
@@ -377,15 +395,17 @@ modifyConst syn fc (PConstant (BI x))
377395modifyConst syn fc x = x
378396
379397{- | Parses a list literal expression e.g. [1,2,3]
398+@
380399ListExpr ::=
381400 '[' ExprList? ']'
382401;
383−
402+@
403+@
384404ExprList ::=
385405 Expr
386406 | Expr ',' ExprList
387407 ;
388−
408+@
389409 -}
390410listExpr :: SyntaxInfo -> IdrisParser PTerm
391411listExpr syn = do lchar '['; fc <- getFC; xs <- sepBy (expr syn) (lchar ','); lchar ']'
@@ -398,22 +418,26 @@ listExpr syn = do lchar '['; fc <- getFC; xs <- sepBy (expr syn) (lchar ','); lc
398418
399419
400420{- | Parses an alternative expression
421+@
401422 Alt ::= '(|' Expr_List '|)';
402423
403424 Expr_List ::=
404425 Expr'
405426 | Expr' ',' Expr_List
406427 ;
428+@
407429-}
408430alt :: SyntaxInfo -> IdrisParser PTerm
409431alt syn = do symbol "(|"; alts <- sepBy1 (expr' syn) (lchar ','); symbol "|)"
410432 return (PAlternative False alts)
411433
412434{- | Parses a possibly hidden simple expression
435+@
413436HSimpleExpr ::=
414437 '.' SimpleExpr
415438 | SimpleExpr
416439 ;
440+@
417441-}
418442hsimpleExpr :: SyntaxInfo -> IdrisParser PTerm
419443hsimpleExpr syn =
@@ -424,9 +448,11 @@ hsimpleExpr syn =
424448 <?> "expression"
425449
426450{- | Parses a matching application expression
451+@
427452MatchApp ::=
428453 SimpleExpr '<==' FnName
429454 ;
455+@
430456-}
431457matchApp :: SyntaxInfo -> IdrisParser PTerm
432458matchApp syn = do ty <- simpleExpr syn
@@ -451,9 +477,11 @@ unifyLog syn = do lchar '%'; reserved "unifyLog";
451477 <?> "unification log expression"
452478
453479{- | Parses a no implicits expression
480+@
454481NoImplicits ::=
455482 '%' 'noImplicits' SimpleExpr
456483 ;
484+@
457485-}
458486noImplicits :: SyntaxInfo -> IdrisParser PTerm
459487noImplicits syn = do lchar '%'; reserved "noImplicits";
@@ -462,10 +490,12 @@ noImplicits syn = do lchar '%'; reserved "noImplicits";
462490 <?> "no implicits expression"
463491
464492{- | Parses a function application expression
493+@
465494App ::=
466495 'mkForeign' Arg Arg*
467496 | SimpleExpr Arg+
468497 ;
498+@
469499-}
470500app :: SyntaxInfo -> IdrisParser PTerm
471501app syn = do f <- reserved "mkForeign"
@@ -499,12 +529,14 @@ app syn = do f <- reserved "mkForeign"
499529 = desugar (syn { dsl_info = d }) i (getTm a)
500530 dslify i t = t
501531
502−{- |Parses a function argument
532+{-| Parses a function argument
533+@
503534Arg ::=
504535 ImplicitArg
505536 | ConstraintArg
506537 | SimpleExpr
507538 ;
539+@
508540-}
509541arg :: SyntaxInfo -> IdrisParser PArg
510542arg syn = implicitArg syn
@@ -513,10 +545,12 @@ arg syn = implicitArg syn
513545 return (pexp e)
514546 <?> "function argument"
515547
516−{- |Parses an implicit function argument
548+{-| Parses an implicit function argument
549+@
517550ImplicitArg ::=
518551 '{' Name ('=' Expr)? '}'
519552 ;
553+@
520554-}
521555implicitArg :: SyntaxInfo -> IdrisParser PArg
522556implicitArg syn = do lchar '{'
@@ -528,10 +562,12 @@ implicitArg syn = do lchar '{'
528562 return (pimp n v False)
529563 <?> "implicit function argument"
530564
531−{- |Parses a constraint argument (for selecting a named type class instance)
532−ConstraintArg ::=
533− '@{' Expr '}'
534− ;
565+{-| Parses a constraint argument (for selecting a named type class instance)
566+
567+> ConstraintArg ::=
568+> '@{' Expr '}'
569+> ;
570+
535571-}
536572constraintArg :: SyntaxInfo -> IdrisParser PArg
537573constraintArg syn = do symbol "@{"
@@ -541,18 +577,22 @@ constraintArg syn = do symbol "@{"
541577 <?> "constraint argument"
542578
543579
544−{- |Parses a record field setter expression
580+{-| Parses a record field setter expression
581+@
545582RecordType ::=
546583 'record' '{' FieldTypeList '}';
547−
584+@
585+@
548586FieldTypeList ::=
549587 FieldType
550588 | FieldType ',' FieldTypeList
551589 ;
552−
590+@
591+@
553592FieldType ::=
554593 FnName '=' Expr
555594 ;
595+@
556596-}
557597recordType :: SyntaxInfo -> IdrisParser PTerm
558598recordType syn
@@ -579,17 +619,21 @@ recordType syn
579619 applyAll fc ((n, e) : es) x
580620 = applyAll fc es (PApp fc (PRef fc (mkType n)) [pexp e, pexp x])
581621
582−{- |Creates setters for record types on necessary functions -}
622+-- | Creates setters for record types on necessary functions
583623mkType :: Name -> Name
584624mkType (UN n) = UN ("set_" ++ n)
585625mkType (MN 0 n) = MN 0 ("set_" ++ n)
586626mkType (NS n s) = NS (mkType n) s
587627
588−{- |Parses a type signature
628+{- | Parses a type signature
629+@
589630TypeSig ::=
590631 ':' Expr
591632 ;
633+@
634+@
592635TypeExpr ::= ConstraintList? Expr;
636+@
593637 -}
594638typeExpr :: SyntaxInfo -> IdrisParser PTerm
595639typeExpr syn = do cs <- if implicitAllowed syn then constraintList syn else return []
@@ -597,15 +641,19 @@ typeExpr syn = do cs <- if implicitAllowed syn then constraintList syn else retu
597641 return (bindList (PPi constraint) (map (\x -> (MN 0 "c", x)) cs) sc)
598642 <?> "type signature"
599643
600−{- |Parses a lambda expression
644+{- | Parses a lambda expression
645+@
601646Lambda ::=
602647 '\\' TypeOptDeclList '=>' Expr
603648 | '\\' SimpleExprList '=>' Expr
604649 ;
650+@
651+@
605652SimpleExprList ::=
606653 SimpleExpr
607654 | SimpleExpr ',' SimpleExprList
608655 ;
656+@
609657-}
610658lambda :: SyntaxInfo -> IdrisParser PTerm
611659lambda syn = do lchar '\\'
@@ -627,10 +675,12 @@ lambda syn = do lchar '\\'
627675 (PCase fc (PRef fc (MN i "lamp"))
628676 [(x, pmList xs sc)])
629677
630−{- |Parses a term rewrite expression
678+{- | Parses a term rewrite expression
679+@
631680RewriteTerm ::=
632681 'rewrite' Expr ('==>' Expr)? 'in' Expr
633682 ;
683+@
634684-}
635685rewriteTerm :: SyntaxInfo -> IdrisParser PTerm
636686rewriteTerm syn = do reserved "rewrite"
@@ -644,6 +694,7 @@ rewriteTerm syn = do reserved "rewrite"
644694 <?> "term rewrite expression"
645695
646696{- |Parses a let binding
697+@
647698Let ::=
648699 'let' Name TypeSig'? '=' Expr 'in' Expr
649700| 'let' Expr' '=' Expr' 'in' Expr
@@ -651,6 +702,7 @@ Let ::=
651702TypeSig' ::=
652703 ':' Expr'
653704 ;
705+@
654706 -}
655707let_ :: SyntaxInfo -> IdrisParser PTerm
656708let_ syn = try (do reserved "let"; n <- name;
@@ -665,10 +717,13 @@ let_ syn = try (do reserved "let"; n <- name;
665717 return (PCase fc v [(pat, sc)]))
666718 <?> "let binding"
667719
668−{- |Parses a quote goal
720+{- | Parses a quote goal
721+
722+@
669723QuoteGoal ::=
670724 'quoteGoal' Name 'by' Expr 'in' Expr
671725 ;
726+@
672727 -}
673728quoteGoal :: SyntaxInfo -> IdrisParser PTerm
674729quoteGoal syn = do reserved "quoteGoal"; n <- name;
@@ -680,13 +735,15 @@ quoteGoal syn = do reserved "quoteGoal"; n <- name;
680735 return (PGoal fc r n sc)
681736 <?> "quote goal expression"
682737
683−{- |Parses a dependent type signature
738+{- | Parses a dependent type signature
739+@
684740Pi ::=
685741 '|'? Static? '(' TypeDeclList ')' DocComment '->' Expr
686742 | '|'? Static? '{' TypeDeclList '}' '->' Expr
687743 | '{' 'auto' TypeDeclList '}' '->' Expr
688744 | '{' 'default' TypeDeclList '}' '->' Expr
689745 ;
746+@
690747 -}
691748
692749pi :: SyntaxInfo -> IdrisParser PTerm
@@ -728,10 +785,13 @@ pi syn =
728785 <?> "dependent type signature"
729786
730787{- | Parses a type constraint list
788+
789+@
731790ConstraintList ::=
732791 '(' Expr_List ')' '=>'
733792 | Expr '=>'
734793 ;
794+@
735795-}
736796constraintList :: SyntaxInfo -> IdrisParser [PTerm]
737797constraintList syn = try (do lchar '('
@@ -745,16 +805,20 @@ constraintList syn = try (do lchar '('
745805 <|> return []
746806 <?> "type constraint list"
747807
748−{- |Parses a type declaration list
808+{- | Parses a type declaration list
809+@
749810TypeDeclList ::=
750811 FunctionSignatureList
751812 | NameList TypeSig
752813 ;
814+@
753815
816+@
754817FunctionSignatureList ::=
755818 Name TypeSig
756819 | Name TypeSig ',' FunctionSignatureList
757820 ;
821+@
758822-}
759823typeDeclList :: SyntaxInfo -> IdrisParser [(Name, PTerm)]
760824typeDeclList syn = try (sepBy1 (do x <- fnName
@@ -768,13 +832,17 @@ typeDeclList syn = try (sepBy1 (do x <- fnName
768832 return (map (\x -> (x, t)) ns)
769833 <?> "type declaration list"
770834
771−{- |Parses a type declaration list with optional parameters
835+{- | Parses a type declaration list with optional parameters
836+@
772837TypeOptDeclList ::=
773838 NameOrPlaceholder TypeSig?
774839 | NameOrPlaceholder TypeSig? ',' TypeOptDeclList
775840 ;
841+@
776842
843+@
777844NameOrPlaceHolder ::= Name | '_';
845+@
778846-}
779847tyOptDeclList :: SyntaxInfo -> IdrisParser [(Name, PTerm)]
780848tyOptDeclList syn = sepBy1 (do x <- nameOrPlaceholder
@@ -789,13 +857,17 @@ tyOptDeclList syn = sepBy1 (do x <- nameOrPlaceholder
789857 return (MN 0 "underscore")
790858 <?> "name or placeholder"
791859
792−{- |Parses a list comprehension
860+{- | Parses a list comprehension
861+@
793862Comprehension ::= '[' Expr '|' DoList ']';
863+@
794864
865+@
795866DoList ::=
796867 Do
797868 | Do ',' DoList
798869 ;
870+@
799871-}
800872comprehension :: SyntaxInfo -> IdrisParser PTerm
801873comprehension syn
@@ -814,12 +886,16 @@ comprehension syn
814886 [pexp e])
815887 addGuard x = x
816888
817−{- |Parses a do-block
889+{- | Parses a do-block
890+@
818891Do' ::= Do KeepTerminator;
892+@
819893
894+@
820895DoBlock ::=
821896 'do' OpenBlock Do'+ CloseBlock
822897 ;
898+@
823899 -}
824900doBlock :: SyntaxInfo -> IdrisParser PTerm
825901doBlock syn
@@ -828,7 +904,8 @@ doBlock syn
828904 return (PDoBlock ds)
829905 <?> "do block"
830906
831−{- |Parses an expression inside a do block
907+{- | Parses an expression inside a do block
908+@
832909Do ::=
833910 'let' Name TypeSig'? '=' Expr
834911 | 'let' Expr' '=' Expr
@@ -836,6 +913,7 @@ Do ::=
836913 | Expr' '<-' Expr
837914 | Expr
838915 ;
916+@
839917-}
840918do_ :: SyntaxInfo -> IdrisParser PDo
841919do_ syn
@@ -868,8 +946,10 @@ do_ syn
868946 return (DoExp fc e)
869947 <?> "do block expression"
870948
871−{- |Parses an expression in idiom brackets
949+{- | Parses an expression in idiom brackets
950+@
872951Idiom ::= '[|' Expr '|]';
952+@
873953-}
874954idiom :: SyntaxInfo -> IdrisParser PTerm
875955idiom syn
@@ -881,6 +961,8 @@ idiom syn
881961 <?> "expression in idiom brackets"
882962
883963{- |Parses a constant or literal expression
964+
965+@
884966Constant ::=
885967 'Integer'
886968 | 'Int'
@@ -901,6 +983,7 @@ Constant ::=
901983 | String_t
902984 | Char_t
903985 ;
986+@
904987-}
905988constant :: IdrisParser Idris.Core.TT.Const
906989constant = do reserved "Integer";return (AType (ATInt ITBig))
@@ -923,17 +1006,22 @@ constant = do reserved "Integer";return (AType (ATInt ITBig))
9231006 <|> try (do c <- charLiteral; return $ Ch c)
9241007 <?> "constant or literal"
9251008
926−{- |Parses a static modifier
1009+{- | Parses a static modifier
1010+
1011+@
9271012Static ::=
9281013 '[' static ']'
9291014;
1015+@
9301016-}
9311017static :: IdrisParser Static
9321018static = do lchar '['; reserved "static"; lchar ']'; return Static
9331019 <|> return Dynamic
9341020 <?> "static modifier"
9351021
936−{- | Parses a tactic script
1022+{- | Parses a tactic script
1023+
1024+@
9371025Tactic ::= 'intro' NameList?
9381026 | 'intros'
9391027 | 'refine' Name Imp+
@@ -967,7 +1055,7 @@ TacticSeq ::=
9671055 Tactic ';' Tactic
9681056 | Tactic ';' TacticSeq
9691057 ;
970−
1058+@
9711059-}
9721060
9731061tactic :: SyntaxInfo -> IdrisParser PTactic
@@ -986,6 +1074,8 @@ tactic syn = do reserved "intro"; ns <- sepBy (indentPropHolds gtProp *> name) (
9861074 <|> do reserved "rewrite"; t <- (indentPropHolds gtProp *> expr syn);
9871075 i <- get
9881076 return $ Rewrite (desugar syn i t)
1077+ <|> do reserved "induction"; nm <- (indentPropHolds gtProp *> name);
1078+ return $ Induction nm
9891079 <|> do reserved "equiv"; t <- (indentPropHolds gtProp *> expr syn);
9901080 i <- get
9911081 return $ Equiv (desugar syn i t)
@@ -1040,7 +1130,7 @@ tactic syn = do reserved "intro"; ns <- sepBy (indentPropHolds gtProp *> name) (
10401130 mergeSeq [t] = t
10411131 mergeSeq (t:ts) = TSeq t (mergeSeq ts)
10421132
1043−{- | Parses a tactic as a whole -}
1133+-- | Parses a tactic as a whole
10441134fullTactic :: SyntaxInfo -> IdrisParser PTactic
10451135fullTactic syn = do t <- tactic syn
10461136 eof
src/Idris/ParseOps.hs+23−14
@@ -29,8 +29,8 @@ import qualified Data.HashSet as HS
2929import qualified Data.Text as T
3030import qualified Data.ByteString.UTF8 as UTF8
3131
32−{- |Creates table for fixity declarations to build expression parser using
33− pre-build and user-defined operator/fixity declarations -}
32+-- | Creates table for fixity declarations to build expression parser
33+-- using pre-build and user-defined operator/fixity declarations
3434table :: [FixDecl] -> OperatorTable IdrisParser PTerm
3535table fixes
3636 = [[prefix "-" (\fc x -> PApp fc (PRef fc (UN "-"))
@@ -40,7 +40,7 @@ table fixes
4040 [binary "=" PEq AssocLeft],
4141 [binary "->" (\fc x y -> PPi expl (MN 42 "__pi_arg") x y) AssocRight]]
4242
43−{- |Calculates table for fixtiy declarations -}
43+-- | Calculates table for fixtiy declarations
4444toTable :: [FixDecl] -> OperatorTable IdrisParser PTerm
4545toTable fs = map (map toBin)
4646 (groupBy (\ (Fix x _) (Fix y _) -> prec x == prec y) fs)
@@ -52,20 +52,20 @@ toTable fs = map (map toBin)
5252 assoc (Infixr _) = AssocRight
5353 assoc (InfixN _) = AssocNone
5454
55−{- |Binary operator -}
55+-- | Binary operator
5656binary :: String -> (FC -> PTerm -> PTerm -> PTerm) -> Assoc -> Operator IdrisParser PTerm
5757binary name f = Infix (do fc <- getFC
5858 reservedOp name
5959 doc <- option "" (docComment '^')
6060 return (f fc))
6161
62−{- |Prefix operator -}
62+-- | Prefix operator
6363prefix :: String -> (FC -> PTerm -> PTerm) -> Operator IdrisParser PTerm
6464prefix name f = Prefix (do reservedOp name
6565 fc <- getFC
6666 return (f fc))
6767
68−{- |Backtick operator -}
68+-- | Backtick operator
6969backtick :: Operator IdrisParser PTerm
7070backtick = Infix (do lchar '`'; n <- fnName
7171 lchar '`'
@@ -75,22 +75,29 @@ backtick = Infix (do lchar '`'; n <- fnName
7575{- | Parses an operator in function position i.e. enclosed by `()', with an
7676 optional namespace
7777
78+@
7879 OperatorFront ::= (Identifier_t '.')? '(' Operator_t ')';
80+@
81+
7982-}
8083operatorFront :: IdrisParser Name
8184operatorFront = maybeWithNS (lchar '(' *> operator <* lchar ')') False []
8285
8386{- | Parses a function (either normal name or operator)
84− FnName ::= Name | OperatorFront;
87+
88+@
89+ FnName ::= Name | OperatorFront;
90+@
8591-}
8692fnName :: IdrisParser Name
8793fnName = try operatorFront <|> name <?> "function name"
8894
8995{- | Parses a fixity declaration
90−
96+@
9197Fixity ::=
9298 FixityType Natural_t OperatorList Terminator
9399 ;
100+@
94101-}
95102fixity :: IdrisParser PDecl
96103fixity = do pushIndent
@@ -121,12 +128,14 @@ fixity = do pushIndent
121128 extractName (Fix _ n) = n
122129
123130{- | Parses a fixity declaration type (i.e. infix or prefix, associtavity)
124−FixityType ::=
125− 'infixl'
126− | 'infixr'
127− | 'infix'
128− | 'prefix'
129− ;
131+@
132+ FixityType ::=
133+ 'infixl'
134+ | 'infixr'
135+ | 'infix'
136+ | 'prefix'
137+ ;
138+@
130139 -}
131140fixityType :: IdrisParser (Int -> Fixity)
132141fixityType = do reserved "infixl"; return Infixl
src/Idris/Parser.hs+47−17
@@ -437,16 +437,35 @@ namespace syn =
437437 return [PNamespace n (concat ds)]
438438 <?> "namespace declaration"
439439
440−{- |Parses a methods block (for type classes and instances)
441− MethodsBlock ::= 'where' OpenBlock FnDecl* CloseBlock
440+{- |Parses a methods block (for instances)
441+ InstanceBlock ::= 'where' OpenBlock FnDecl* CloseBlock
442442 -}
443−methodsBlock :: SyntaxInfo -> IdrisParser [PDecl]
444−methodsBlock syn = do reserved "where"
445− openBlock
446− ds <- many (fnDecl syn)
447− closeBlock
448− return (concat ds)
449− <?> "methods block"
443+instanceBlock :: SyntaxInfo -> IdrisParser [PDecl]
444+instanceBlock syn = do reserved "where"
445+ openBlock
446+ ds <- many (fnDecl syn)
447+ closeBlock
448+ return (concat ds)
449+ <?> "instance block"
450+
451+{- |Parses a methods and instances block (for type classes)
452+
453+MethodOrInstance ::=
454+ FnDecl
455+ | Instance
456+ ;
457+
458+ClassBlock ::=
459+ 'where' OpenBlock MethodOrInstance* CloseBlock
460+ ;
461+-}
462+classBlock :: SyntaxInfo -> IdrisParser [PDecl]
463+classBlock syn = do reserved "where"
464+ openBlock
465+ ds <- many ((notEndBlock >> instance_ syn) <|> fnDecl syn)
466+ closeBlock
467+ return (concat ds)
468+ <?> "class block"
450469
451470{- |Parses a type class declaration
452471
@@ -456,7 +475,7 @@ ClassArgument ::=
456475 ;
457476
458477Class ::=
459− DocComment_t? Accessibility? 'class' ConstraintList? Name ClassArgument* MethodsBlock?
478+ DocComment_t? Accessibility? 'class' ConstraintList? Name ClassArgument* ClassBlock?
460479 ;
461480-}
462481class_ :: SyntaxInfo -> IdrisParser [PDecl]
@@ -467,7 +486,7 @@ class_ syn = do (doc, acc) <- try (do
467486 reserved "class"; fc <- getFC; cons <- constraintList syn; n_in <- name
468487 let n = expandNS syn n_in
469488 cs <- many carg
470− ds <- option [] (methodsBlock syn)
489+ ds <- option [] (classBlock syn)
471490 accData acc n (concatMap declared ds)
472491 return [PClass doc syn fc cons n cs ds]
473492 <?> "type-class declaration"
@@ -481,7 +500,7 @@ class_ syn = do (doc, acc) <- try (do
481500{- |Parses a type class instance declaration
482501
483502 Instance ::=
484− 'instance' InstanceName? ConstraintList? Name SimpleExpr* MethodsBlock?
503+ 'instance' InstanceName? ConstraintList? Name SimpleExpr* InstanceBlock?
485504 ;
486505
487506 InstanceName ::= '[' Name ']';
@@ -494,9 +513,9 @@ instance_ syn = do reserved "instance"; fc <- getFC
494513 args <- many (simpleExpr syn)
495514 let sc = PApp fc (PRef fc cn) (map pexp args)
496515 let t = bindList (PPi constraint) (map (\x -> (MN 0 "c", x)) cs) sc
497− ds <- option [] (methodsBlock syn)
516+ ds <- option [] (instanceBlock syn)
498517 return [PInstance syn fc cs cn args t en ds]
499− <?> "instance declaratioN"
518+ <?> "instance declaration"
500519 where instanceName :: IdrisParser Name
501520 instanceName = do lchar '['; n_in <- fnName; lchar ']'
502521 let n = expandNS syn n_in
@@ -797,6 +816,7 @@ Directive' ::= 'lib' CodeGen String_t
797816 | 'default' Totality
798817 | 'logging' Natural
799818 | 'dynamic' StringList
819+ | 'name' Name NameList
800820 | 'language' 'TypeProviders'
801821 | 'language' 'ErrorReflection'
802822 ;
@@ -839,6 +859,12 @@ directive syn = do try (lchar '%' *> reserved "lib"); cgn <- codegen_; lib <- st
839859 Left lib -> addIBC (IBCDyLib (lib_name lib))
840860 Right msg ->
841861 fail $ msg)]
862+ <|> do try (lchar '%' *> reserved "name")
863+ ty <- iName []
864+ ns <- sepBy1 name (lchar ',')
865+ return [PDirective
866+ (do mapM_ (addNameHint ty) ns
867+ mapM_ (\n -> addIBC (IBCNameHint (ty, n))) ns)]
842868 <|> do try (lchar '%' *> reserved "language"); ext <- pLangExt;
843869 return [PDirective (addLangExt ext)]
844870 <?> "directive"
@@ -919,7 +945,8 @@ findFC :: Doc -> (FC, String)
919945findFC x = let s = show (plain x) in
920946 case span (/= ':') s of
921947 (failname, ':':rest) -> case span isDigit rest of
922− (line, ':':rest') -> (FC failname (read line) 0, drop 2 (dropWhile (/= ':') rest'))
948+ (line, ':':rest') -> case span isDigit rest' of
949+ (col, ':':msg) -> (FC failname (read line) (read col), msg)
923950
924951-- | A program is a list of declarations, possibly with associated
925952-- documentation strings.
@@ -1021,7 +1048,7 @@ loadSource h lidr f
10211048 f file pos
10221049 unless (null ds') $ do
10231050 let ds = namespaces mname ds'
1024− logLvl 3 (dumpDecls ds)
1051+ logLvl 3 (showDecls True ds)
10251052 i <- getIState
10261053 logLvl 10 (show (toAlist (idris_implicits i)))
10271054 logLvl 3 (show (idris_infixes i))
@@ -1047,7 +1074,10 @@ loadSource h lidr f
10471074 -- Redo totality check for deferred names
10481075 let deftots = idris_defertotcheck i
10491076 iLOG $ "Totality checking " ++ show deftots
1050− mapM_ (\x -> setTotality x Unchecked) (map snd deftots)
1077+ mapM_ (\x -> do tot <- getTotality x
1078+ case tot of
1079+ Total _ -> setTotality x Unchecked
1080+ _ -> return ()) (map snd deftots)
10511081 mapM_ buildSCG deftots
10521082 mapM_ checkDeclTotality deftots
10531083
src/Idris/REPL.hs+25−18
@@ -224,9 +224,7 @@ ideslave orig mods
224224 do clearErr
225225 putIState (orig { idris_options = idris_options i,
226226 idris_outputmode = (IdeSlave id) })
227− idrisCatch (do mod <- loadModule' stdout filename
228− return ())
229− (setAndReport)
227+ loadInputs stdout [filename]
230228 isetPrompt (mkPrompt [filename])
231229 -- Report either success or failure
232230 i <- getIState
@@ -346,7 +344,7 @@ processInput stvar cmd orig inputs
346344 , idris_colourTheme = idris_colourTheme i
347345 }
348346 clearErr
349− mod <- loadModule stdout f
347+ mod <- loadInputs stdout [f]
350348 return (Just [f])
351349 Success (ModImport f) ->
352350 do clearErr
@@ -629,7 +627,8 @@ process h fn (AddMissing updatefile l n)
629627
630628 extras <- case lookupCtxt n' (idris_patdefs i) of
631629 [] -> return ""
632− [(_, tms)] -> showNew (show n ++ "_rhs") 1 indent tms
630+ [(_, tms)] -> do tms' <- nameMissing tms
631+ showNew (show n ++ "_rhs") 1 indent tms'
633632 let (nonblank, rest) = span (not . all isSpace) (tyline:later)
634633 if updatefile
635634 then do let fb = fn ++ "~"
@@ -708,7 +707,7 @@ process h fn (DoProofSearch updatefile l n hints)
708707 if updatefile then
709708 do let fb = fn ++ "~"
710709 runIO $ writeFile fb (unlines before ++
711− updateMeta tyline (show n) newmv ++ "\n"
710+ updateMeta False tyline (show n) newmv ++ "\n"
712711 ++ unlines later)
713712 runIO $ copyFile fb fn
714713 else ihPrintResult h newmv
@@ -726,16 +725,23 @@ process h fn (DoProofSearch updatefile l n hints)
726725 nsroot (SN (WhereN _ _ n)) = nsroot n
727726 nsroot n = n
728727
729− updateMeta ('?':cs) n new
728+ updateMeta brack ('?':cs) n new
730729 | length cs >= length n
731730 = case splitAt (length n) cs of
732731 (mv, c:cs) ->
733732 if (isSpace c && mv == n)
734− then new ++ (c : cs)
735− else '?' : mv ++ c : updateMeta cs n new
736− (mv, []) -> if (mv == n) then new else '?' : mv
737− updateMeta (c:cs) n new = c : updateMeta cs n new
738− updateMeta [] n new = ""
733+ then addBracket brack new ++ (c : cs)
734+ else '?' : mv ++ c : updateMeta True cs n new
735+ (mv, []) -> if (mv == n) then addBracket brack new else '?' : mv
736+ updateMeta brack ('=':cs) n new = '=':updateMeta False cs n new
737+ updateMeta brack (c:cs) n new
738+ = c : updateMeta (brack || not (isSpace c)) cs n new
739+ updateMeta brack [] n new = ""
740+
741+ addBracket False new = new
742+ addBracket True new@('(':xs) | last xs == ')' = new
743+ addBracket True new | any isSpace new = '(' : new ++ ")"
744+ | otherwise = new
739745
740746process h fn (Spec t)
741747 = do (tm, ty) <- elabVal toplevel False t
@@ -1094,6 +1100,7 @@ idrisMain opts =
10941100 let nobanner = NoBanner `elem` opts
10951101 let idesl = Ideslave `elem` opts
10961102 let runrepl = not (NoREPL `elem` opts)
1103+ let verbose = runrepl || Verbose `elem` opts
10971104 let output = opt getOutput opts
10981105 let ibcsubdir = opt getIBCSubDir opts
10991106 let importdirs = opt getImportDir opts
@@ -1126,14 +1133,13 @@ idrisMain opts =
11261133 setREPL runrepl
11271134 setQuiet (quiet || isJust script)
11281135 setIdeSlave idesl
1129− setVerbose runrepl
1136+ setVerbose verbose
11301137 setCmdLine opts
11311138 setOutputTy outty
11321139 setCodegen cgn
11331140 setTargetTriple trpl
11341141 setTargetCPU tcpu
11351142 setOptLevel optimize
1136− when (Verbose `elem` opts) $ setVerbose True
11371143 mapM_ makeOption opts
11381144 -- if we have the --bytecode flag, drop into the bytecode assembler
11391145 case bcs of
@@ -1178,10 +1184,11 @@ idrisMain opts =
11781184
11791185 historyFile <- fmap (</> "repl" </> "history") getIdrisUserDataDir
11801186
1181− when (runrepl && not idesl) $ initScript
1182− stvar <- runIO $ newMVar ist
1183− when (runrepl && not idesl) $ startServer ist stvar inputs
1184− when (runrepl && not idesl) $ runInputT (replSettings (Just historyFile)) $ repl ist stvar inputs
1187+ when (runrepl && not idesl) $ do
1188+ initScript
1189+ stvar <- runIO $ newMVar ist
1190+ startServer ist stvar inputs
1191+ runInputT (replSettings (Just historyFile)) $ repl ist stvar inputs
11851192 when (idesl) $ ideslaveStart ist inputs
11861193 ok <- noErrors
11871194 when (not ok) $ runIO (exitWith (ExitFailure 1))
src/Pkg/Package.hs+1−1
@@ -70,7 +70,7 @@ installPkg pkgdesc
7070 mapM_ (installObj (pkgname pkgdesc)) (objs pkgdesc)
7171
7272buildMods :: [Opt] -> [Name] -> IO ()
73−buildMods opts ns = do let f = map (toPath . show) ns
73+buildMods opts ns = do let f = map (toPath . showCG) ns
7474-- putStrLn $ "MODULE: " ++ show f
7575 idris (map Filename f ++ opts)
7676 return ()
test/reg028/expected+2−2
@@ -1,2 +1,2 @@
1−reg028.idr:5:1:tbad.bad is possibly not total due to: {tbad.bad12}
2−reg028a.idr:11:1:tbad.qsort' is possibly not total due to: {tbad.qsort'14}
1+reg028.idr:5:1:tbad.bad is possibly not total due to: {tbad.bad16}
2+reg028a.idr:11:1:tbad.qsort' is possibly not total due to: {tbad.qsort'18}
test/test032/expected+3−3
@@ -1,8 +1,8 @@
11Type checking ./test032.idr
22isElem x [] = ?isElem_rhs_1
3−isElem x (_ :: _) = ?isElem_rhs_3
3+isElem x (y :: xs) = ?isElem_rhs_3
44
5− localZipWith f (_ :: _) (_ :: _) = ?localZipWith_rhs_1
5+ localZipWith f (_ :: _) (x :: ys) = ?localZipWith_rhs_1
66
77f x :: (map f xs)
88isElem2 x (y :: ys) with (_)
@@ -10,5 +10,5 @@ isElem2 x (y :: ys) with (_)
1010 isElem3 x (x :: ys) | (Yes refl) = ?isElem3_rhs_3
1111
1212 [] => ?bar_1
13− (_ :: _) => ?bar_2
13+ (x :: ys) => ?bar_2
1414
test/test035/expectednew file

No changes to the content.

test/test035/runnew file+3
@@ -0,0 +1,3 @@
1+#!/usr/bin/env bash
2+idris --check $@ test035.idr
3+rm -f *.ibc
test/test035/test035.idrnew file+9
@@ -0,0 +1,9 @@
1+module Main
2+
3+import Syntax.PreorderReasoning
4+import Control.Isomorphism
5+
6+stupidProof : Iso (Either a b) (Either a b)
7+stupidProof {a} {b} = (Either a b) ={ eitherComm }=
8+ (Either b a) ={ eitherComm }=
9+ (Either a b) QED