on master help sign in
Merge pull request #3420 from jfdm/doc-movement
f852094Jan de Muijnck-Hughes
docs/reference/index.rst+3
@@ -31,7 +31,10 @@ This will tell you how Idris works, for using it you should read the Idris Tutor
31 tactics
31 tactics
32 repl
32 repl
33 compilation
33 compilation
34+ internals
34 language-features
35 language-features
35 language-extensions
36 language-extensions
36 elaborator-reflection
37 elaborator-reflection
38+ type-directed-search
39+ partial-evaluation
37 misc
40 misc
docs/reference/internals.rstnew file+172
@@ -0,0 +1,172 @@
1+Note: this is still a fairly raw set of notes taken by David
2+Christiansen at Edwin's presentation at the 2013 Idris Developers
3+Meeting. They're in the process of turning into a useful guide - feel
4+free to contribute.
5+
6+This document assumes that you are already familiar with Idris. It is
7+intended for those who want to work on the internals.
8+
9+People looking to develop new back ends may want to look at [[Idris back
10+end IRs\|Idris-back-end-IRs]]
11+
12+Core/TT.hs
13+==========
14+
15+Idris is compiled to a simple, explicit core language. This core
16+language is called TT because it looks a bit like a Π. It's a minimal
17+language, with a locally nameless representation. That is, local
18+variables are represented with de Bruijn indices and globally-defined
19+constants are represented with names.
20+
21+The ``TT`` datatype uses a trick that is common in the Idris code: it is
22+polymorphic over the type of names stored in it, and it derives
23+``Functor``. This allows ``fmap`` to be used as a general-purpose
24+traversal.
25+
26+There is a general construction for binders, used for λ, Π, and
27+let-bindings. These are distinguished using a ``BinderType``.
28+
29+During compilation, some terms (especially types) will be erased. This
30+is represented using the ``Erased`` constructor of ``TT``. A handy trick
31+when generating TT terms is to insert ``Erased`` where a term is
32+uniquely determined, as the typechecker will fill it out.
33+
34+The constructor ``Proj`` is a result of the optimizer. It is used to
35+extract a specific constructor argument, in a more economical way than
36+defining a new pattern-matching operation.
37+
38+The datatype ``Raw`` represents terms that have not yet been
39+typechecked. The typechecker converts a ``Raw`` to a ``TT`` if it can.
40+
41+Core/CaseTree.hs
42+================
43+
44+Case trees are used to represent top-level pattern-matching definitions
45+in the TT language.
46+
47+Just as with the ``TT`` datatype, the ``deriving Functor`` trick is used
48+with ``SC`` and ``CaseAlt`` to get GHC to generate a function for
49+mapping over contained terms.
50+
51+Constructor cases (``ConCase`` in ``CaseAlt``) refer to numbered
52+constructors. Every constructor is numbered 0,1,2,…. At this stage in
53+the compiler, the tags are datatype-local. After defunctionalization,
54+however, they are made globally unique.
55+
56+The ``n+1`` patterns (``SucCase``) and hacky-seeming things are to make
57+code fast -- please ask before "cleaning up" the representation.
58+
59+Core/Evaluate.hs
60+================
61+
62+This module contains the main evaluator for Idris. The evaluator is used
63+both at the REPL and during type checking, where normalised terms need
64+to be compared for equality.
65+
66+A key datatype in the evaluator is a *context*. Contexts are mappings
67+from global names to their values, but they are organized to make
68+type-directed disambiguation quick. In particular, the main part of a
69+name that a user might type is used as the key, and its values are maps
70+from namespaces to actual values.
71+
72+The datatype ``Def`` represents a definition in the global context. All
73+global names map to this structure.
74+
75+``Type`` and ``Term`` are both synonyms for ``TT``.
76+
77+Datatypes are represented by a ``TyDecl`` with the appropriate
78+``NameType``. A ``Function`` is a global constant term with an annotated
79+type, ``Operator`` represents primitives implemented in Haskell, and
80+``CaseOp`` represents ordinary pattern-matching definitions. ``CaseOp``
81+has four versions for different purposes, and all are saved because
82+that's easiest.
83+
84+``CaseInfo``: the ``tc_dictionary`` is because it's a type class
85+dictionary which makes totality checking easier.
86+
87+The ``normalise*`` functions give different behaviors - but
88+``normalise`` is the most common.
89+
90+``normaliseC`` - "resolved" means with names converted to de Bruijn
91+indices as appropriate.
92+
93+``normaliseAll`` - reduce everything, even if it's non-total
94+
95+``normaliseTrace`` - special-purpose for debugging
96+
97+``simplify`` - reduce the things that are small - the list argument is
98+the things to not reduce.
99+
100+Core/Typecheck.hs
101+=================
102+
103+Standard stuff. Hopefully no changes are necessary.
104+
105+Core/Elaborate.hs
106+=================
107+
108+Idris definitions are elaborated one by one and turned into the
109+corresponding TT. This is done with a tactic language as an EDSL in the
110+Elab monad (or Elab' when there's a custom state).
111+
112+Lots of plumbing for errors.
113+
114+All elaboration is relative to a global context.
115+
116+The string in the pair returned by elaborate is log information.
117+
118+See JFP paper, but the names don't necessarily map to each other. The
119+paper is the "idealized version" without logging, additional state, etc.
120+
121+All the tactics take Raws, typechecking happens there.
122+
123+claim (x : t) assumes a new x : t.
124+
125+PLEASE TIDY THINGS UP!
126+
127+proofSearch flag to try' is whether the failure came from a human (so
128+fail) or from a machine (so continue)
129+
130+Idris-level syntax for providing alternatives explicitly: (\| x, y, z
131+\|) try x, y, z in order, and take the first that succeeds.
132+
133+Core/ProofState.hs
134+==================
135+
136+Core/Unify.hs
137+=============
138+
139+Deals with unification. Unification can reply with: - this works - this
140+can never work - this will work if these other unification problems work
141+out (eg unifying f x with 1)
142+
143+match\_unify: same thing as unification except it's just matching name
144+against name, term against term. x + y matches to 0 + y with x = 0. Used
145+for <== syntax as well as type class resolution.
146+
147+Idris/AbsSyntaxTree.hs
148+======================
149+
150+PTerm is the datatype of Idris syntax. P is for Program. Each PTerm
151+turns into a TT term by applying a series of tactics.
152+
153+IState is the major interpreter state. The global context is the
154+tt\_ctxt field.
155+
156+Ctxt maps possibly ambiguous names to their referents.
157+
158+Idris/ElabDecls.hs
159+==================
160+
161+This is where the actual elaboration from PTerm to TT happens.
162+
163+Idris/ElabTerm.hs
164+=================
165+
166+build is the function that creates a Raw. All the "junk" is to deal with
167+things like metavars and so forth. It has to remember what names are
168+still to be defined, and it doesn't yet know the type (filled in by
169+unificaiton later). Also case expressions have to turn into top-level
170+functions.
171+
172+resolveTC is type class resolution.
docs/reference/partial-evaluation.rstnew file+305
@@ -0,0 +1,305 @@
1+****************************************
2+Static Arguments and Partial Evaluation
3+****************************************
4+
5+As of version 0.9.15, Idris has support for *partial evaluation* of
6+statically known arguments. This involves creating specialised versions
7+of functions with arguments annotated as ``[static]``.
8+
9+(This is an implementation of the partial evaluator described in `this
10+ICFP 2010
11+paper <http://eb.host.cs.st-andrews.ac.uk/writings/icfp10.pdf>`__.
12+Please refer to this for more precise definitions of what follows.)
13+
14+Partial evaluation is switched on by default. It can be disabled with
15+the ``--no-partial-eval`` flag.
16+
17+Introductory Example
18+--------------------
19+
20+Consider the power function over natural numbers, defined as follows
21+(we'll call it ``my_pow`` since ``pow`` already exists in the Prelude):
22+
23+::
24+
25+ my_pow : Nat -> Nat -> Nat
26+ my_pow x Z = 1
27+ my_pow x (S k) = mult x (my_pow x k)
28+
29+This is implemented by recursion on the second argument, and we can
30+evaluate the definition further if the second argument is known, even if
31+the first isn't. For example, we can build a function at the REPL to
32+cube a number as follows:
33+
34+::
35+
36+ *pow> \x => my_pow x 3
37+ \x => mult x (mult x (mult x 1)) : Nat -> Nat
38+ *pow> it 3
39+ 27 : Nat
40+
41+Note that in the resulting function the recursion has been eliminated,
42+since ``my_pow`` is implemented by recursion on the known argument. We
43+have no such luck if the first argument is known and the second isn't:
44+
45+::
46+
47+ *pow> \x => my_pow 2 x
48+ \x => my_pow 2 x : Nat -> Nat
49+
50+Now, consider the following definition which calculates x^2 + 1:
51+
52+::
53+
54+ powFn : Nat -> Nat
55+ powFn x = plus (my_pow x (S (S Z))) (S Z)
56+
57+Since the second argument to ``my_pow`` here is statically known, it
58+seems a shame to have to make the recursive calls every time. However,
59+Idris will not in general inline recursive definitions, in particular
60+since they may diverge or duplicate work without some deeper analysis.
61+
62+We can, however, give Idris some hints that here we really would like to
63+create a specialised version of ``my_pow``.
64+
65+Automatic specialisation of ``pow``
66+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
67+
68+The trick is to mark the statically known arguments with the
69+``[static]`` flag:
70+
71+::
72+
73+ my_pow : Nat -> [static] Nat -> Nat
74+ my_pow k Z = 1
75+ my_pow k (S j) = mult k (my_pow k j)
76+
77+When an argument is annotated in this way, Idris will try to create a
78+specialised version whenever it accounts a call with a concrete value
79+(i.e. a constant, constructor form, or globally defined function) in a
80+``[static]`` position. If ``my_pow`` is defined this way, and ``powFn``
81+defined as above, we can see the effect by typing ``:printdef powFn`` at
82+the REPL:
83+
84+::
85+
86+ *pow> :printdef powFn
87+ powFn : Nat -> Nat
88+ powFn x = plus (PE_my_pow_3f3e5ad8 x) 1
89+
90+What is this mysterious ``PE_my_pow_3f3e5ad8``? It's a specialised power
91+function where the statically known argument has been specialised away.
92+The name is generated from a hash of the specialised arguments, and we
93+can see its definition with ``:printdef`` too:
94+
95+::
96+
97+ *petest> :printdef PE_my_pow_3f3e5ad8
98+ PE_my_pow_3f3e5ad8 : Nat -> Nat
99+ PE_my_pow_3f3e5ad8 (0arg) = mult (0arg) (mult (0arg) (PE_fromInteger_7ba9767f 1))
100+
101+The ``(0arg)`` is an internal argument name (programmers can't give
102+variable names beginning with a digit after all). Notice also that there
103+is a specialised version of ``fromInteger`` for ``Nat``\ s, since type
104+class dictionaries are themselves a particularly common case of
105+statically known arguments!
106+
107+Specialising Type Classes
108+-------------------------
109+
110+Type class dictionaries are very often statically known, so Idris
111+automatically marks any type class constraint as ``[static]`` and builds
112+specialised versions of top level functions where the class is
113+instantiated. For example, given:
114+
115+::
116+
117+ calc : Int -> Int
118+ calc x = (x * x) + x
119+
120+If we print this definition, we'll see a specialised version of ``+`` is
121+used:
122+
123+::
124+
125+ *petest> :printdef calc
126+ calc : Int -> Int
127+ calc x = PE_+_954510b4 (PE_*_954510b4 x x) x
128+
129+More interestingly, consider ``vadd`` which adds corresponding elements
130+in a vector of anything numeric:
131+
132+::
133+
134+ vadd : Num a => Vect n a -> Vect n a -> Vect n a
135+ vadd [] [] = []
136+ vadd (x :: xs) (y :: ys) = x + y :: vadd xs ys
137+
138+If we use this on something concrete as follows...
139+
140+::
141+
142+ test : List Int -> List Int
143+ test xs = let xs' = fromList xs in
144+ toList $ vadd xs' xs'
145+
146+...then in fact, we get a specialised version of ``vadd`` in the
147+definition of ``test``, and indeed the specialised version of
148+``toList``:
149+
150+::
151+
152+ test : List Int -> List Int
153+ test xs = let xs' = fromList xs
154+ in PE_toList_888ae67 (PE_vadd_33f98d3d xs' xs')
155+
156+Here's the specialised version of ``vadd``:
157+
158+::
159+
160+ PE_vadd_33f98d3d : Vect n Int -> Vect n Int -> Vect n Int
161+ PE_vadd_33f98d3d [] [] = []
162+ PE_vadd_33f98d3d (x :: xs) (y :: ys) = ((PE_+_954510b4 x y) ::
163+ (PE_vadd_33f98d3d xs ys))
164+
165+Note that the recursive structure has been preserved, and the recursive
166+call to ``vadd`` has been replaced with a recursive call to the
167+specialised version. We've also got the same specialised version of
168+``+`` that we had above in ``calc``.
169+
170+Specialising Higher Order Functions
171+-----------------------------------
172+
173+Another case where partial evaluation can be useful is in automatically
174+making specialised versions of higher order functions. Unlike type class
175+dictionaries, this is not done automatically, but we might consider
176+writing ``map`` as follows:
177+
178+::
179+
180+ my_map : [static] (a -> b) -> List a -> List b
181+ my_map f [] = []
182+ my_map f (x :: xs) = f x :: my_map f xs
183+
184+Then using ``my_map`` will yield specialised versions, for example to
185+double every value in a list of ``Int``\ s we could write:
186+
187+::
188+
189+ doubleAll : List Int -> List Int
190+ doubleAll xs = my_map (*2) xs
191+
192+This would yield a specialised version of ``my_map``, used in
193+``doubleAll`` as follows:
194+
195+::
196+
197+ doubleAll : List Int -> List Int
198+ doubleAll xs = PE_my_map_1f8225c4 xs
199+
200+ PE_my_map_1f8225c4 : List Int -> List Int
201+ PE_my_map_1f8225c4 [] = []
202+ PE_my_map_1f8225c4 (x :: xs) = ((PE_*_954510b4 x 2) :: (PE_my_map_1f8225c4 xs))
203+
204+Specialising Interpreters
205+-------------------------
206+
207+A particularly useful situation where partial evaluation becomes
208+effective is in defining an interpreter for a well-typed expression
209+language, defined as follows (see the `Idris tutorial, section
210+4 <http://eb.host.cs.st-andrews.ac.uk/writings/idris-tutorial.pdf>`__
211+for more details on how this works):
212+
213+::
214+
215+ data Expr : Vect n Ty -> Ty -> Type where
216+ Var : HasType i gamma t -> Expr gamma t
217+ Val : (x : Int) -> Expr gamma TyInt
218+ Lam : Expr (a :: gamma) t -> Expr gamma (TyFun a t)
219+ App : Lazy (Expr gamma (TyFun a t)) -> Expr gamma a -> Expr gamma t
220+ Op : (interpTy a -> interpTy b -> interpTy c) -> Expr gamma a -> Expr gamma
221+ Expr gamma c
222+ If : Expr gamma TyBool -> Expr gamma a -> Expr gamma a -> Expr gamma a
223+
224+ dsl expr
225+ lambda = Lam
226+ variable = Var
227+ index_first = stop
228+ index_next = pop
229+
230+We can write a couple of test functions in this language as follows,
231+using the ``dsl`` notation to overload lambdas; first a function which
232+multiplies two inputs:
233+
234+::
235+
236+ eMult : Expr gamma (TyFun TyInt (TyFun TyInt TyInt))
237+ eMult = expr (\x, y => Op (*) x y)
238+
239+Then, a function which calculates the factorial of its input:
240+
241+::
242+
243+ eFac : Expr gamma (TyFun TyInt TyInt)
244+ eFac = expr (\x => If (Op (==) x (Val 0))
245+ (Val 1)
246+ (App (App eMult (App eFac (Op (-) x (Val 1)))) x))
247+
248+The interpreter's type is written as follows, marking the expression to
249+be evaluated as ``[static]``:
250+
251+::
252+
253+ interp : (env : Env gamma) -> [static] (e : Expr gamma t) -> interpTy t
254+
255+This means that if we write an Idris program to calculate a factorial by
256+calling ``interp`` on ``eFac``, the resulting definition will be
257+specialised, partially evaluating away the interpreter:
258+
259+::
260+
261+ runFac : Int -> Int
262+ runFac x = interp [] eFac x
263+
264+We can see that the call to ``interp`` has been partially evaluated away
265+as follows:
266+
267+::
268+
269+ *interp> :printdef runFac
270+ runFac : Int -> Int
271+ runFac x = PE_interp_ed1429e [] x
272+
273+If we look at ``PE_interp_ed1429e`` we'll see that it follows exactly
274+the structur of ``eFac``, with the interpreter evaluated away:
275+
276+::
277+
278+ *interp> :printdef PE_interp_ed1429e
279+ PE_interp_ed1429e : Env gamma -> Int -> Int
280+ PE_interp_ed1429e (3arg) = \x =>
281+ boolElim (x == 0)
282+ (Delay 1)
283+ (Delay (PE_interp_b5c2d0ff (x :: (3arg))
284+ (PE_interp_ed1429e (x :: (3arg)) (x - 1)) x))
285+
286+
287+For the sake of readability, I have simplified this slightly: what you
288+will really see also includes specialised versions of ``==``, ``-`` and
289+``fromInteger``. Note that ``PE_interp_ed1429e``, which represents
290+``eFac`` has become a recursive function following the structure of
291+``eFac``. There is also a call to ``PE_interp_b5c2d0ff`` which is a
292+specialised interpeter for ``eMult``.
293+
294+These definitions arise because the partial evaluator will only
295+specialise a definition by a specific concrete argument once, then it is
296+cached for future use. So any future applications of ``interp`` on
297+``eFac`` will also be translated to ``PE_interp_ed1429e``.
298+
299+The specialised version of ``eMult``, without any simplification for
300+readability, is:
301+
302+::
303+
304+ PE_interp_b5c2d0ff : Env gamma -> Int -> Int -> Int
305+ PE_interp_b5c2d0ff (3arg) = \x => \x1 => PE_*_954510b4 x x1
docs/reference/type-directed-search.rstnew file+336
@@ -0,0 +1,336 @@
1+*********************************
2+Type Directed Search ``:search``
3+*********************************
4+
5+Idris' ``:search`` command searches for terms according to their
6+approximate type signature (much like
7+`Hoogle <http://www.haskell.org/hoogle/>`__ for Haskell). For
8+example::
9+
10+ Idris> :search e -> List e -> List e
11+ = Prelude.List.(::) : a -> List a -> List a
12+ Cons cell
13+
14+ = Prelude.List.intersperse : a -> List a -> List a
15+ Insert some separator between the elements of a list.
16+
17+ > Prelude.List.delete : Eq a => a -> List a -> List a
18+
19+
20+ < assert_smaller : a -> b -> b
21+ Assert to the totality checker than y is always structurally
22+ smaller than x (which is typically a pattern argument)
23+
24+ < Prelude.Basics.const : a -> b -> a
25+ Constant function. Ignores its second argument.
26+
27+The best results are listed first. As we can see, ``(::)`` and
28+``intersperse`` are exact matches; the ``=`` symbol to the left of those
29+results tells us the types of ``(::)`` and ``intersperse`` are
30+effectively the same as the type that was searched.
31+
32+The next result is ``delete``, whose type is more specific than the type
33+that was searched; that's indicated by the ``>`` symbol. If we had a
34+function with the signature ``e -> List e -> List e``, we could have
35+given it the type ``Eq a => a -> List a -> List a``, but not necessarily
36+the other way around.
37+
38+The final two results, ``assert_smaller`` and ``const``, have types more
39+general than the type that was searched, and so they have ``<`` symbols
40+to their left. For example, ``e -> List e -> List e`` would be a valid
41+type for ``assert_smaller``. The correspondence for ``const`` is more
42+complicated than any of the four previous results. ``:search`` shows
43+this result because we could change the order of the arguments! That is,
44+the following definition would be legal:
45+
46+.. code:: idris
47+
48+ f : e -> List e -> List e
49+ f x xs = const xs x
50+
51+About :search results
52+---------------------
53+
54+:search's functionality is based on the notion of type isomorphism.
55+Informally, two types are isomorphic if we can identify terms of one
56+type exactly with terms of the other. For example, we can consider the
57+types ``Nat -> a -> List a`` and ``a -> Nat -> List a`` to be
58+isomorphic, because if we have ``f : Nat -> a -> List a``, then
59+``flip f : a -> Nat -> List a``. Similarly, if
60+``g : a -> Nat -> List a``, then ``flip g : Nat -> a -> List a``.
61+
62+With :search, we create a partial order on types; that is, given two
63+types ``A`` and ``B``, we may choose to say that ``A <= B``, ``A >= B``,
64+or both (in which case we say ``A == B``), or neither. For :search, we
65+say that ``A >= B`` if all of the terms inhabiting ``A`` correspond to
66+terms of ``B``, but it need not necessarily be the case that *all* the
67+terms of ``B`` correspond to terms of ``A``. Here's an example:
68+
69+::
70+
71+ a -> a >= Nat -> Nat
72+
73+The left-hand type has just a single inhabitant, ``id``, which
74+corresponds to the term ``id {a = Nat}``, which has the right-hand type.
75+However, there are various terms inhabiting the right-hand type (such as
76+``S``) which cannot correspond with terms of type ``a -> a``.
77+
78+We can consider the partial order for ``:search`` to be, in some sense,
79+inductively generated by several classes of "edits" which are described
80+below.
81+
82+Possible edits
83+~~~~~~~~~~~~~~
84+
85+Here is a simple approximate list of the edits that are possible in
86+``:search``. They are not entirely formal, and do not necessarily
87+reflect the ``:search`` command's actual behavior. For example, the
88+*argument application* rule may be used directly on arguments that are
89+bound after other arguments, without using several applications of the
90+*argument transposition* rule.
91+
92+- **Argument transposition**
93+
94+ ::
95+
96+ A : Type B : Type a : A, b : B |- M : Type
97+ ----------------------------------------------------------------------------
98+ (x : A) -> (y : B) -> [x,y/a,b]M == (y : B) -> (x : A) -> [x,y/a,b]M
99+
100+ Score: 1 point
101+
102+Example:
103+
104+::
105+
106+ a -> Vect n a -> Vect (S n) a == Vect n a -> a -> Vect (S n) a
107+
108+Note that in order for it to make sense to change the order of
109+arguments, neither of the arguments' types may depend on the value bound
110+by the other argument!
111+
112+- **Symmetry of equality**
113+
114+ ::
115+
116+ A = B : Type t : Type |- M : Type
117+ ----------------------------------------
118+ [A = B/t]M == [B = A/t]M
119+
120+ Score: 1 point
121+
122+Example:
123+
124+::
125+
126+ (x,y,z : Nat) -> x + (y + z) = (x + y) + z
127+ ==
128+ (x,y,z : Nat) -> (x + y) + z = x + (y + z)
129+
130+Note that this rule means that we can flip equalities anywhere they
131+occur (i.e., not only in the return type).
132+
133+- **Argument application**
134+
135+ ::
136+
137+ e : A |- M : Type y1 : T1, ..., yn : Tn |- x : A
138+ -----------------------------------------------------------------
139+ (z : A) -> [z/e]M >= (y1 : T1) -> ... -> (yn :Tn) -> [x/e]M
140+
141+ Score: <= : 3 points, >= : 9 points
142+
143+Examples:
144+
145+::
146+
147+ a -> a >= Nat -> Nat
148+ a -> a >= List e -> List e
149+ Vect k (Fin k) >= Vect 5 (Fin 5)
150+
151+Note that the ``n`` shown in the scheme above may be 0; that is, there
152+are no Pi terms to be added on the right side. For example, that's the
153+case for the first example shown above. This is probably the most
154+important, and most widely used, rule of all.
155+
156+- **Type class application**
157+
158+ ::
159+
160+ C : Type -> TypeClass
161+ , y1 : T1, ..., yn : Tn |- A : Type, instance : C A
162+ , t : Type |- M : Type
163+ -----------------------------------------------------------------
164+ C a => [a/t]M >= (y1 : T1) -> ... -> (yn : Tn) -> [A/t]M
165+
166+ Score: <= : 4 points, >= : 12 points
167+
168+Examples
169+
170+::
171+
172+ Ord a => a >= Int
173+ Show (List e) => List e -> String >= Show a => List a -> String
174+
175+This rule is used by looking at the instances for a particular type
176+class. While the scheme is shown only for single-parameter type classes,
177+it naturally generalizes to multi-parameter type classes. This rule is
178+particularly useful in conjunction with argument application. Again,
179+note that the ``n`` in the scheme above may be 0.
180+
181+- **Type class introduction**
182+
183+ ::
184+
185+ t : Type |- M : Type C : Type -> TypeClass
186+ -----------------------------------------------
187+ (t : Type) -> M >= C t => M
188+
189+ Score: <= : 2 points, >= : 6 points
190+
191+Example:
192+
193+::
194+
195+ a -> a -> Bool >= Eq a => a -> a -> Bool
196+
197+Scoring and listing search results
198+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
199+
200+When a type ``S`` is searched, the type is compared against the types of
201+all of the terms which are currently in context. When :search compares
202+two types ``S`` and ``T``, it essentially tries to find a chain of
203+inequalities
204+
205+::
206+
207+ R1 R2 Rn Rn+1
208+ S <= A1 <= ... <= An <= T
209+
210+using the edit rules listed above. It also tries to find chains going
211+the other way (i.e., showing ``S >= T``) as well. Each rule has an
212+associated score which indicates how drastic of a change the rule
213+corresponds to. These scores are listed above. Note that for the rules
214+which are not symmetric, the score depends on the direction in which the
215+rule is used. Finding types which are more general that the searched
216+typed (``S <= T``) is preferred to finding types which are less general.
217+
218+The score for the entire chain is, at minimum, the sum of the scores of
219+the individual rules (some non-linear interactions may be added). The
220+:search function tries to find the chain between ``S`` and ``T`` which
221+results in the lowest score, and this is the score associated to the
222+search result for ``T``.
223+
224+Search results are listed in order of ascending score. The symbol which
225+is shown along with the search result reflects the type of the chain
226+which resulted in the minimum score.
227+
228+Implementation of :search
229+-------------------------
230+
231+Practically, naive and undirected application of the rules enumerated
232+above is not possible; not only is this obviously inefficient, but the
233+two application rules (particularly *argument application*) are really
234+impossible to use without context given by other types. Therefore, we
235+use a heuristic algorithm that is meant to be practical, though it might
236+not find ways to relate two types which may actually be related by the
237+rules listed above.
238+
239+Suppose we wish to match two types, ``S`` and ``T``. We think of the
240+problem as a non-deterministic state machine. There is a ``State``
241+datatype which keeps track of how well we've matched ``S`` and ``T`` so
242+far. It contains:
243+
244+- Names of argument variables (Pi-bound variables) in either type which
245+ have yet to be matched
246+- A directed acyclic graph (DAG) of arguments (Pi-bindings) for ``S``
247+ and ``T`` which have yet to be matched
248+- A list of typeclass constraints for ``S`` and ``T`` which have yet to
249+ be matched
250+- A record of the rules which have been used so far to get to this
251+ point
252+
253+A function ``nextSteps : State -> [State]`` finds the next states which
254+may follow from a given state. Some states, where everything has been
255+matched, are considered final. The algorithm can be roughly broken down
256+into multiple stages; if we start from having two types, ``S`` and
257+``T``, which we wish to match, they are as follows:
258+
259+1. For each of ``S`` and ``T``, split the types up into their return
260+ types and directed acyclic graphs of the arguments, where there is an
261+ edge from argument A to argument B if the term bound in A appears in
262+ the type of B. The topological sorts of the DAG represent all the
263+ possible ways in which the arguments may be permuted.
264+2. For type ``T``, recursively find (saturated) uses of the ``=`` type
265+ constructor and produce a list of modified versions of ``T``
266+ containing all possible flips of the ``=`` constructor (this
267+ corresponds to the *symmetry of equality rule*).
268+3. For each modified type for ``T``, try to unify the return type of the
269+ modified ``T`` with ``S``, considering arguments from both ``S`` and
270+ ``T`` to be holes, so that the unifier may match pieces of the two
271+ types. For each modified version of ``T`` where this succeeds, an
272+ initial ``State`` can be made. The arguments and typeclasses are
273+ updated accordingly with the results of unification. The remainder of
274+ the algorithm involves applying ``nextSteps`` to these states until
275+ either no states remain (corresponding to no path from ``S`` to
276+ ``T``) or a final state is found. ``nextSteps`` also has several
277+ stages:
278+4. Try to unify arguments of ``S`` with arguments of ``T``, much like is
279+ done with the return types. We work "backwards" through the
280+ arguments: we try matching all remaining arguments of ``S`` which
281+ lack outgoing edges in the DAG of remaining arguments (that is, the
282+ bound value doesn't appear in the type of any other remaining
283+ arguments) with the all of the corresponding remaining arguments of
284+ ``T``. This is done recursively until no arguments remain for both
285+ ``S`` and ``T``; otherwise, we give up at this point. This step
286+ corresponds to application of the *argument application rule*, as
287+ well as the *argument transposition* rule.
288+5. Now, we try to match the type classes. First, we take all possible
289+ subsets of type class constraints for ``S`` and ``T``. So if ``S``
290+ and ``T`` have a total of ``n`` type class constraints, this produces
291+ ``2^n`` states for every state, and this quickly becomes infeasible
292+ as ``n`` grows large. This is probably the biggest bottleneck of the
293+ algorithm at the moment. This step corresponds to applications of the
294+ *type class introduction* rule.
295+6. Try to match type class constraints for ``S`` with those for ``T``.
296+ We attempt to unify each type class constraint for ``S`` with each
297+ constraint for ``T``. This may result in applications of the *type
298+ class application* rule. Once we are unable to match any more type
299+ class constraints between ``S`` and ``T``, we proceed to the final
300+ step.
301+7. Try instantiating type classes with their instances (in either ``S``
302+ or ``T``). This corresponds to applications of the *type class
303+ application* rule. After instantiating a type class, we hopefully
304+ open up more opportunities to match typeclass constraints of ``S``
305+ with those of ``T``, so we return to the previous step.
306+
307+The code for :search is located in the `Idris.TypeSearch
308+module <https://github.com/idris-lang/Idris-dev/blob/master/src/Idris/TypeSearch.hs>`__.
309+
310+Aggregating results
311+~~~~~~~~~~~~~~~~~~~
312+
313+The search for chains of rules/edits which relate two types can be
314+viewed as a shortest path problem where nodes correspond to types and
315+edges correspond to rules relating two types. The weights or distances
316+on each edge correspond to the score of each rule. We then may imagine
317+that we have a single start node, our search type ``S``, and several
318+final nodes: all of the types for terms which are currently in context.
319+The problem, then, is to find the shortest paths (where they exist) to
320+all of the final nodes. In particular, we wish to find the "closest"
321+types (those with the minimum score) first, as we'd like to display them
322+first.
323+
324+This problem nicely maps to usage of Dijkstra's algorithm. We search for
325+all types simultaneously so we can find the closest ones with the
326+minimum amount of work. In practice, this results in using a priority
327+queue of priority queues. We first ask "which goal type should we work
328+on next?", and then ask "which state should we expand upon next?" By
329+using this strategy, the best results can be shown quickly, even if it
330+takes a bit of time to find worse results (or at least rule them out).
331+
332+Miscellaneous Notes
333+-------------------
334+
335+Whether arguments are explicit or implicit does not affect search
336+results.
docs/tutorial/typesfuns.rst+3−2
@@ -469,7 +469,7 @@ It is a matter of taste whether you want to do this — sometimes it can
469help document a function by making the purpose of an argument more
469help document a function by making the purpose of an argument more
470clear.
470clear.
471
471
472−Furthermore, ``{}`` can be used to pattern match on the left hand side, i.e.
472+Furthermore, ``{}`` can be used to pattern match on the left hand side, i.e.
473``{var = pat}`` gets an implicit variable and attempts to pattern match on "pat";
473``{var = pat}`` gets an implicit variable and attempts to pattern match on "pat";
474For example :
474For example :
475
475
@@ -1074,7 +1074,7 @@ The syntax ``record { field = val, ... }`` generates a function which
1074updates the given fields in a record. ``=`` assigns a new value to a field,
1074updates the given fields in a record. ``=`` assigns a new value to a field,
1075and ``$=`` applies a function to update its value.
1075and ``$=`` applies a function to update its value.
1076
1076
1077−Each record is defined in its own namespace, which means that field names
1077+Each record is defined in its own namespace, which means that field names
1078can be reused in multiple records.
1078can be reused in multiple records.
1079
1079
1080Records, and fields within records, can have dependent types. Updates
1080Records, and fields within records, can have dependent types. Updates
@@ -1331,6 +1331,7 @@ at runtime if called on an empty list. (This is similar to the behavior of
1331Haskell's ``head`` function.) ``unsafeHead`` might look like this:
1331Haskell's ``head`` function.) ``unsafeHead`` might look like this:
1332
1332
1333.. code-block:: idris
1333.. code-block:: idris
1334+
1334 -- Unsafe head example!
1335 -- Unsafe head example!
1335 unsafeHead : List a -> a
1336 unsafeHead : List a -> a
1336 unsafeHead (x::xs) = x
1337 unsafeHead (x::xs) = x