on master help sign in
Merge branch 'master' into cabal-library
0f97368Brian McKenna
.gitignore+2
@@ -1,5 +1,7 @@
1dist
1dist
2cabal-dev/
2cabal-dev/
3+.cabal-sandbox
4+cabal.sandbox.config
3*.ibc
5*.ibc
4*.o
6*.o
5*.a
7*.a
.travis.yml+8−4
@@ -3,6 +3,9 @@ before_install:
3 - sudo add-apt-repository --yes ppa:h-rayflood/llvm
3 - sudo add-apt-repository --yes ppa:h-rayflood/llvm
4 - sudo apt-get update -qq
4 - sudo apt-get update -qq
5 - sudo apt-get install -qq libgc-dev llvm-3.3
5 - sudo apt-get install -qq libgc-dev llvm-3.3
6+ - sudo apt-get install -qq libghc-unordered-containers-dev libghc-mtl-dev libghc-network-dev libghc-xml-dev libghc-transformers-dev libghc-text-dev libghc-utf8-string-dev libghc-vector-dev libghc-split-dev libghc-ansi-terminal-dev libghc-ansi-wl-pprint-dev
7+ # trifecta dependencies
8+ - sudo apt-get install -qq libghc-blaze-builder-dev libghc-blaze-html-dev libghc-data-lens-dev libghc-bifunctors-dev libghc-hashable-dev libghc-semigroups-dev libghc-semigroupoids-dev libghc-parallel-dev libghc-comonad-dev libghc-terminfo-dev libghc-keys-dev
6install:
9install:
7 - cabal install -f FFI -f LLVM --only-dependencies --enable-tests
10 - cabal install -f FFI -f LLVM --only-dependencies --enable-tests
8before_script:
11before_script:
@@ -14,7 +17,8 @@ script:
14 - cabal configure -f FFI -f LLVM
17 - cabal configure -f FFI -f LLVM
15 - cabal build
18 - cabal build
16 - cabal copy
19 - cabal copy
17− - make -j2 test
20+ - make -j2 $TESTS
18− - make -j2 test_llvm
21+env:
22+ - TESTS=test
19− - make -j2 test_java
23+ - TESTS=test_java
20−
24+ - TESTS=test_llvm
CHANGELOG+17−14
@@ -5,30 +5,33 @@ New in 0.9.10:
5 types may now depend on earlier methods.
5 types may now depend on earlier methods.
6* More flexible class instance resolution, so that function types and lambda
6* More flexible class instance resolution, so that function types and lambda
7 expressions can be made instances of a type class.
7 expressions can be made instances of a type class.
8−* Add '%reflection' option for functions, for compile-time operations on
9− syntax.
10−* Add 'quoteGoal x by p in e' which makes x equal to p applied to the goal
11− in the scope e
12* Add !expr notation for implicit binding of intermediate results in
8* Add !expr notation for implicit binding of intermediate results in
13− monadic/do/etc expressions
9+ monadic/do/etc expressions.
14* Extend Effects package to cope with possibly failing operations, using
10* Extend Effects package to cope with possibly failing operations, using
15− "if_valid", "if_error", etc
11+ "if_valid", "if_error", etc.
16−* At the REPL, "it" now refers to the previous expression
12+* At the REPL, "it" now refers to the previous expression.
17* Semantic colouring at the REPL. Turn this off with --nocolour.
13* Semantic colouring at the REPL. Turn this off with --nocolour.
18−* Some prettifying of error message
14+* Some prettifying of error messages.
19* The contents of ~/.idris/repl/init are run at REPL start-up.
15* The contents of ~/.idris/repl/init are run at REPL start-up.
20−* The REPL stores a command history in ~/.idris/repl/history
16+* The REPL stores a command history in ~/.idris/repl/history.
21* The [a..b], [a,b..c], [a..], and [a,b..] syntax now pass the totality
17* The [a..b], [a,b..c], [a..], and [a,b..] syntax now pass the totality
22 checker and can thus be used in types. The [x..] syntax now returns an
18 checker and can thus be used in types. The [x..] syntax now returns an
23 actually infinite stream.
19 actually infinite stream.
20+* Add '%reflection' option for functions, for compile-time operations on
21+ syntax.
22+* Add expression form 'quoteGoal x by p in e' which applies p to the expected
23+ expression type and binds the result to x in the scope e.
24+* Performance improvements in Strings library.
25+* Library reorganisation, separated into prelude/ and base/.
24
26
25Internal changes
27Internal changes
26
28
27−* New module/dependency tree checking
29+* New module/dependency tree checking.
28−* New parser implementation with more precise errors
30+* New parser implementation with more precise errors.
29−* Improved type class resolution
31+* Improved type class resolution.
30−* Compiling Nat via GMP integers
32+* Compiling Nat via GMP integers.
31−* Performance improvements in elaboration
33+* Performance improvements in elaboration.
34+* Improvements in termination checking.
32* Various REPL commands to support interactive editing, and a client/server
35* Various REPL commands to support interactive editing, and a client/server
33 mode to allow external invocation of REPL commands.
36 mode to allow external invocation of REPL commands.
34
37
Setup.hs+12−1
@@ -53,6 +53,13 @@ usesLLVM flags =
53 Just False -> False
53 Just False -> False
54 Nothing -> True
54 Nothing -> True
55
55
56+usesGMP :: S.ConfigFlags -> Bool
57+usesGMP flags =
58+ case lookup (FlagName "gmp") (S.configConfigurationsFlags flags) of
59+ Just True -> True
60+ Just False -> False
61+ Nothing -> True
62+
56-- -----------------------------------------------------------------------------
63-- -----------------------------------------------------------------------------
57-- Clean
64-- Clean
58
65
@@ -101,10 +108,14 @@ idrisBuild _ flags _ local = do
101 where
108 where
102 makeBuild dir = make verbosity [ "-C", dir, "build" , "IDRIS=" ++ idrisCmd local]
109 makeBuild dir = make verbosity [ "-C", dir, "build" , "IDRIS=" ++ idrisCmd local]
103
110
104− buildRTS = make verbosity ["-C", "rts", "build"]
111+ buildRTS = make verbosity (["-C", "rts", "build"] ++
112+ gmpflag (usesGMP (configFlags local)))
105
113
106 buildLLVM = make verbosity ["-C", "llvm", "build"]
114 buildLLVM = make verbosity ["-C", "llvm", "build"]
107
115
116+ gmpflag False = []
117+ gmpflag True = ["GMP=-DIDRIS_GMP"]
118+
108-- -----------------------------------------------------------------------------
119-- -----------------------------------------------------------------------------
109-- Copy/Install
120-- Copy/Install
110
121
tutorial/examples/Makefile → examples/Makefilerenamed

The content is the same.

tutorial/examples/binary.idr → examples/binary.idrrenamed

The content is the same.

tutorial/examples/bmain.idr → examples/bmain.idrrenamed

The content is the same.

tutorial/examples/btree.idr → examples/btree.idrrenamed

The content is the same.

tutorial/examples/classes.idr → examples/classes.idrrenamed

The content is the same.

tutorial/examples/foo.idr → examples/foo.idrrenamed

The content is the same.

tutorial/examples/hello.idr → examples/hello.idrrenamed

The content is the same.

tutorial/examples/idiom.idr → examples/idiom.idrrenamed

The content is the same.

tutorial/examples/interp.idr → examples/interp.idrrenamed

The content is the same.

tutorial/examples/letbind.idr → examples/letbind.idrrenamed

The content is the same.

tutorial/examples/prims.idr → examples/prims.idrrenamed

The content is the same.

tutorial/examples/theorems.idr → examples/theorems.idrrenamed

The content is the same.

tutorial/examples/universe.idr → examples/universe.idrrenamed

The content is the same.

tutorial/examples/usefultypes.idr → examples/usefultypes.idrrenamed

The content is the same.

tutorial/examples/vbroken.idr → examples/vbroken.idrrenamed

The content is the same.

tutorial/examples/views.idr → examples/views.idrrenamed

The content is the same.

tutorial/examples/wheres.idr → examples/wheres.idrrenamed

The content is the same.

idris-tutorial.pdfnew file

Binary file not shown.

idris.cabal+12−1
@@ -301,6 +301,11 @@ Flag FFI
301 Default: False
301 Default: False
302 manual: True
302 manual: True
303
303
304+Flag GMP
305+ Description: Use GMP for Integers
306+ Default: False
307+ manual: True
308+
304Library
309Library
305 hs-source-dirs: src
310 hs-source-dirs: src
306 Exposed-modules:
311 Exposed-modules:
@@ -409,6 +414,9 @@ Library
409 if flag(FFI)
414 if flag(FFI)
410 build-depends: libffi
415 build-depends: libffi
411 cpp-options: -DIDRIS_FFI
416 cpp-options: -DIDRIS_FFI
417+ if flag(GMP)
418+ build-depends: libffi
419+ cpp-options: -DIDRIS_GMP
412
420
413Executable idris
421Executable idris
414 Main-is: Main.hs
422 Main-is: Main.hs
@@ -499,7 +507,7 @@ Executable idris
499 , directory >= 1.2
507 , directory >= 1.2
500 , filepath
508 , filepath
501 , haskeline >= 0.7
509 , haskeline >= 0.7
502− , language-java >= 0.2.2
510+ , language-java >= 0.2.6
503 , mtl
511 , mtl
504 --, parsec >= 3
512 --, parsec >= 3
505 , parsers == 0.9
513 , parsers == 0.9
@@ -548,4 +556,7 @@ Executable idris
548 if flag(FFI)
556 if flag(FFI)
549 build-depends: libffi
557 build-depends: libffi
550 cpp-options: -DIDRIS_FFI
558 cpp-options: -DIDRIS_FFI
559+ if flag(GMP)
560+ build-depends: libffi
561+ cpp-options: -DIDRIS_GMP
551
562
libs/base/Data/BoundedList.idr−1
@@ -77,7 +77,6 @@ map f (x :: xs) = f x :: map f xs
77-- Misc
77-- Misc
78--------------------------------------------------------------------------------
78--------------------------------------------------------------------------------
79
79
80−%assert_total -- not sure why this isn't accepted - clearly decreasing on n
81pad : (xs : BoundedList a n) -> (padding : a) -> BoundedList a n
80pad : (xs : BoundedList a n) -> (padding : a) -> BoundedList a n
82pad {n=Z} [] _ = []
81pad {n=Z} [] _ = []
83pad {n=S n'} [] padding = padding :: (pad {n=n'} [] padding)
82pad {n=S n'} [] padding = padding :: (pad {n=n'} [] padding)
libs/base/Data/Heap.idr+5−20
@@ -5,6 +5,7 @@
5
5
6module Data.Heap
6module Data.Heap
7
7
8+%default total
8%access public
9%access public
9
10
10abstract data MaxiphobicHeap : Type -> Type where
11abstract data MaxiphobicHeap : Type -> Type where
@@ -82,12 +83,12 @@ insert e = merge $ singleton e
82--------------------------------------------------------------------------------
83--------------------------------------------------------------------------------
83
84
84findMinimum : (h : MaxiphobicHeap a) -> (isEmpty h = False) -> a
85findMinimum : (h : MaxiphobicHeap a) -> (isEmpty h = False) -> a
85−findMinimum Empty p = ?findMinimumEmptyAbsurd
86+findMinimum Empty refl impossible
86−findMinimum (Node s l e r) p = e
87+findMinimum (Node s l e r) p = e
87
88
88deleteMinimum : Ord a => (h : MaxiphobicHeap a) -> (isEmpty h = False) -> MaxiphobicHeap a
89deleteMinimum : Ord a => (h : MaxiphobicHeap a) -> (isEmpty h = False) -> MaxiphobicHeap a
89−deleteMinimum Empty p = ?deleteMinimumEmptyAbsurd
90+deleteMinimum Empty refl impossible
90−deleteMinimum (Node s l e r) p = merge l r
91+deleteMinimum (Node s l e r) p = merge l r
91
92
92--------------------------------------------------------------------------------
93--------------------------------------------------------------------------------
93-- Conversions to and from lists (and a derived heap sorting algorithm)
94-- Conversions to and from lists (and a derived heap sorting algorithm)
@@ -173,22 +174,6 @@ isEmptySizeZeroNodeAbsurd = proof {
173 exact p;
174 exact p;
174}
175}
175
176
176−findMinimumEmptyAbsurd = proof {
177− intros;
178− refine FalseElim;
179− refine absurdBoolDischarge;
180− rewrite p;
181− trivial;
182−}
183−
184−deleteMinimumEmptyAbsurd = proof {
185− intros;
186− refine FalseElim;
187− refine absurdBoolDischarge;
188− rewrite p;
189− trivial;
190−}
191−
192--------------------------------------------------------------------------------
177--------------------------------------------------------------------------------
193-- Debug
178-- Debug
194--------------------------------------------------------------------------------
179--------------------------------------------------------------------------------
libs/base/Network/Cgi.idr+7−8
@@ -2,6 +2,8 @@ module Network.Cgi
2
2
3import System
3import System
4
4
5+%default total
6+
5public
7public
6Vars : Type
8Vars : Type
7Vars = List (String, String)
9Vars = List (String, String)
@@ -106,14 +108,11 @@ getVars seps query = mapMaybe readVar (split (\x => elem x seps) query)
106 | _ = Nothing
108 | _ = Nothing
107
109
108getContent : Int -> IO String
110getContent : Int -> IO String
109−getContent x = getC x "" where
111+getContent x = getC (toNat x) "" where
110− %assert_total
111− getC : Int -> String -> IO String
112+ getC : Nat -> String -> IO String
112− getC 0 acc = return $ reverse acc
113+ getC Z acc = return $ reverse acc
113− getC n acc = if (n > 0)
114− then do x <- getChar
114+ getC (S k) acc = do x <- getChar
115− getC (n-1) (strCons x acc)
115+ getC k (strCons x acc)
116− else (return "")
117
116
118getCgiEnv : String -> IO String
117getCgiEnv : String -> IO String
119getCgiEnv key = do
118getCgiEnv key = do
libs/prelude/Prelude.idr+47−7
@@ -40,11 +40,48 @@ instance Show Integer where
40instance Show Float where
40instance Show Float where
41 show = prim__floatToStr
41 show = prim__floatToStr
42
42
43+asciiTab : Vect 32 String
44+asciiTab = ["NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
45+ "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI",
46+ "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
47+ "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US"]
48+
49+firstCharIs : (Char -> Bool) -> String -> Bool
50+firstCharIs p s with (strM s)
51+ firstCharIs p "" | StrNil = False
52+ firstCharIs p (strCons c cs) | StrCons c cs = p c
53+
54+protectEsc : (Char -> Bool) -> String -> String -> String
55+protectEsc p f s = f ++ (if firstCharIs p s then "\\&" else "") ++ s
56+
57+showLitChar : Char -> String -> String
58+showLitChar '\a' = ("\\a" ++)
59+showLitChar '\b' = ("\\b" ++)
60+showLitChar '\f' = ("\\f" ++)
61+showLitChar '\n' = ("\\n" ++)
62+showLitChar '\r' = ("\\r" ++)
63+showLitChar '\t' = ("\\t" ++)
64+showLitChar '\v' = ("\\v" ++)
65+showLitChar '\SO' = protectEsc (== 'H') "\\SO"
66+showLitChar '\DEL' = ("\\DEL" ++)
67+showLitChar '\\' = ("\\\\" ++)
68+showLitChar c = case (integerToFin (cast (cast {to=Int} c)) 32) of
69+ Just k => strCons '\\' . ((index k asciiTab) ++)
70+ Nothing => if (c > '\DEL')
71+ then strCons '\\' . protectEsc isDigit (show (cast {to=Int} c))
72+ else strCons c
73+
74+showLitString : List Char -> String -> String
75+showLitString [] = id
76+showLitString ('"'::cs) = ("\\\"" ++) . showLitString cs
77+showLitString (c ::cs) = showLitChar c . showLitString cs
78+
43instance Show Char where
79instance Show Char where
44− show x = strCons x ""
80+ show '\'' = "'\\''"
81+ show c = strCons '\'' (showLitChar c "'")
45
82
46instance Show String where
83instance Show String where
47− show = id
84+ show cs = strCons '"' (showLitString (cast cs) "\"")
48
85
49instance Show Nat where
86instance Show Nat where
50 show n = show (the Integer (cast n))
87 show n = show (the Integer (cast n))
@@ -328,9 +365,8 @@ instance Enum Nat where
328 fromNat = id
365 fromNat = id
329 enumFromThen n inc = n :: enumFromThen (fromNat (plus (toNat inc) (toNat n))) inc
366 enumFromThen n inc = n :: enumFromThen (fromNat (plus (toNat inc) (toNat n))) inc
330 enumFromThenTo _ Z _ = []
367 enumFromThenTo _ Z _ = []
331− enumFromThenTo n inc m = map (plus n . (* inc)) (natRange (S (( m - n) `div` inc)))
368+ enumFromThenTo n inc m = map (plus n . (* inc)) (natRange (S ((m - n) `div` inc)))
332− enumFromTo n m = map (plus n) (natRange (S (m - n)))
369+ enumFromTo n m = map (plus n) (natRange ((S m) - n))
333−
334
370
335instance Enum Integer where
371instance Enum Integer where
336 pred n = n - 1
372 pred n = n - 1
@@ -338,7 +374,9 @@ instance Enum Integer where
338 toNat n = cast n
374 toNat n = cast n
339 fromNat n = cast n
375 fromNat n = cast n
340 enumFromThen n inc = n :: enumFromThen (inc + n) inc
376 enumFromThen n inc = n :: enumFromThen (inc + n) inc
377+ enumFromTo n m = if n <= m
341− enumFromTo n m = go (natRange (S (cast {to = Nat} (m - n))))
378+ then go (natRange (S (cast {to = Nat} (m - n))))
379+ else []
342 where go : List Nat -> List Integer
380 where go : List Nat -> List Integer
343 go [] = []
381 go [] = []
344 go (x :: xs) = n + cast x :: go xs
382 go (x :: xs) = n + cast x :: go xs
@@ -354,7 +392,9 @@ instance Enum Int where
354 toNat n = cast n
392 toNat n = cast n
355 fromNat n = cast n
393 fromNat n = cast n
356 enumFromThen n inc = n :: enumFromThen (inc + n) inc
394 enumFromThen n inc = n :: enumFromThen (inc + n) inc
395+ enumFromTo n m = if n <= m
357− enumFromTo n m = go (natRange (S (cast {to = Nat} (m - n))))
396+ then go (natRange (S (cast {to = Nat} (m - n))))
397+ else []
358 where go : List Nat -> List Int
398 where go : List Nat -> List Int
359 go [] = []
399 go [] = []
360 go (x :: xs) = n + cast x :: go xs
400 go (x :: xs) = n + cast x :: go xs
libs/prelude/Prelude/Chars.idr+26
@@ -1,43 +1,69 @@
1+-- | Functions operating over Char's
1module Prelude.Char
2module Prelude.Char
2
3
3import Builtins
4import Builtins
4
5
6+-- | Return the ASCII representation of the character.
7+chr : Int -> Char
8+chr x = prim__intToChar x
9+
10+-- | Convert the number to its ASCII equivalent.
11+ord : Char -> Int
12+ord x = prim__charToInt x
13+
14+-- | Returns true if the character is in the range [A-Z].
5isUpper : Char -> Bool
15isUpper : Char -> Bool
6isUpper x = x >= 'A' && x <= 'Z'
16isUpper x = x >= 'A' && x <= 'Z'
7
17
18+-- | Returns true if the character is in the range [a-z]
8isLower : Char -> Bool
19isLower : Char -> Bool
9isLower x = x >= 'a' && x <= 'z'
20isLower x = x >= 'a' && x <= 'z'
10
21
22+-- | Returns true if the character is in the ranges [A-Z][a-z].
11isAlpha : Char -> Bool
23isAlpha : Char -> Bool
12isAlpha x = isUpper x || isLower x
24isAlpha x = isUpper x || isLower x
13
25
26+-- | Returns true if the character is in the range [0-9]
14isDigit : Char -> Bool
27isDigit : Char -> Bool
15isDigit x = (x >= '0' && x <= '9')
28isDigit x = (x >= '0' && x <= '9')
16
29
30+-- | Returns true if the character is in the ranges [A-Z][a-z][0-9]
17isAlphaNum : Char -> Bool
31isAlphaNum : Char -> Bool
18isAlphaNum x = isDigit x || isAlpha x
32isAlphaNum x = isDigit x || isAlpha x
19
33
34+-- | Returns true if the character is a whitespace character.
20isSpace : Char -> Bool
35isSpace : Char -> Bool
21isSpace x = x == ' ' || x == '\t' || x == '\r' ||
36isSpace x = x == ' ' || x == '\t' || x == '\r' ||
22 x == '\n' || x == '\f' || x == '\v' ||
37 x == '\n' || x == '\f' || x == '\v' ||
23 x == '\xa0'
38 x == '\xa0'
24
39
40+-- | Returns true if the character represents a new line.
25isNL : Char -> Bool
41isNL : Char -> Bool
26isNL x = x == '\r' || x == '\n'
42isNL x = x == '\r' || x == '\n'
27
43
44+-- | Convert a letter to the corresponding upper-case letter, if any.
45+-- Non-letters are ignored.
28toUpper : Char -> Char
46toUpper : Char -> Char
29toUpper x = if (isLower x)
47toUpper x = if (isLower x)
30 then (prim__intToChar (prim__charToInt x - 32))
48 then (prim__intToChar (prim__charToInt x - 32))
31 else x
49 else x
32
50
51+-- | Convert a letter to the corresponding lower-case letter, if any.
52+-- Non-letters are ignored.
33toLower : Char -> Char
53toLower : Char -> Char
34toLower x = if (isUpper x)
54toLower x = if (isUpper x)
35 then (prim__intToChar (prim__charToInt x + 32))
55 then (prim__intToChar (prim__charToInt x + 32))
36 else x
56 else x
37
57
58+-- | Returns true if the character is a hexadecimal digit i.e. in the range [0-9][a-f][A-F]
38isHexDigit : Char -> Bool
59isHexDigit : Char -> Bool
39isHexDigit x = elem (toUpper x) hexChars where
60isHexDigit x = elem (toUpper x) hexChars where
40 hexChars : List Char
61 hexChars : List Char
41 hexChars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
62 hexChars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
42 'A', 'B', 'C', 'D', 'E', 'F']
63 'A', 'B', 'C', 'D', 'E', 'F']
43
64
65+-- | Returns true if the character is an octal digit.
66+isOctDigit : Char -> Bool
67+isOctDigit x = (x >= '0' && x <= '7')
68+
69+-- --------------------------------------------------------------------- [ EOF ]
libs/prelude/Prelude/Classes.idr+82−10
@@ -11,7 +11,7 @@ infixl 7 <<, >>
11infixl 8 +,-
11infixl 8 +,-
12infixl 9 *,/
12infixl 9 *,/
13
13
14−-- ------------------------------------------------------- [ Numeric Operators ]
14+-- ------------------------------------------------------------- [ Boolean Ops ]
15intToBool : Int -> Bool
15intToBool : Int -> Bool
16intToBool 0 = False
16intToBool 0 = False
17intToBool x = True
17intToBool x = True
@@ -19,6 +19,7 @@ intToBool x = True
19boolOp : (a -> a -> Int) -> a -> a -> Bool
19boolOp : (a -> a -> Int) -> a -> a -> Bool
20boolOp op x y = intToBool (op x y)
20boolOp op x y = intToBool (op x y)
21
21
22+-- ---------------------------------------------------------- [ Equality Class ]
22-- | The Eq class defines inequality and equality.
23-- | The Eq class defines inequality and equality.
23class Eq a where
24class Eq a where
24 (==) : a -> a -> Bool
25 (==) : a -> a -> Bool
@@ -47,11 +48,12 @@ instance Eq Bool where
47 True == False = False
48 True == False = False
48 False == True = False
49 False == True = False
49 False == False = True
50 False == False = True
50−
51+
51instance (Eq a, Eq b) => Eq (a, b) where
52instance (Eq a, Eq b) => Eq (a, b) where
52 (==) (a, c) (b, d) = (a == b) && (c == d)
53 (==) (a, c) (b, d) = (a == b) && (c == d)
53
54
54
55
56+-- ---------------------------------------------------------- [ Ordering Class ]
55data Ordering = LT | EQ | GT
57data Ordering = LT | EQ | GT
56
58
57instance Eq Ordering where
59instance Eq Ordering where
@@ -123,6 +125,7 @@ instance (Ord a, Ord b) => Ord (a, b) where
123 then compare xl yl
125 then compare xl yl
124 else compare xr yr
126 else compare xr yr
125
127
128+-- --------------------------------------------------------- [ Numerical Class ]
126-- | The Num class defines basic numerical arithmetic.
129-- | The Num class defines basic numerical arithmetic.
127class Num a where
130class Num a where
128 (+) : a -> a -> a
131 (+) : a -> a -> a
@@ -234,17 +237,86 @@ instance Ord Bits64 where
234 else if l > r then GT
237 else if l > r then GT
235 else EQ
238 else EQ
236
239
237−-- | Integer division.
238−partial
239−div : Integer -> Integer -> Integer
240−div = prim__sdivBigInt
241
240
242−-- | Integer modulus.
241+-- ------------------------------------------------------------- [ Fractionals ]
243−partial
244−mod : Integer -> Integer -> Integer
245−mod = prim__sremBigInt
246
242
247-- | Fractional division of two Floats.
243-- | Fractional division of two Floats.
248(/) : Float -> Float -> Float
244(/) : Float -> Float -> Float
249(/) = prim__divFloat
245(/) = prim__divFloat
250
246
247+
248+-- --------------------------------------------------------------- [ Integrals ]
249+%default partial
250+
251+class Integral a where
252+ div : a -> a -> a
253+ mod : a -> a -> a
254+
255+-- ---------------------------------------------------------------- [ Integers ]
256+divBigInt : Integer -> Integer -> Integer
257+divBigInt = prim__sdivBigInt
258+
259+modBigInt : Integer -> Integer -> Integer
260+modBigInt = prim__sremBigInt
261+
262+instance Integral Integer where
263+ div = divBigInt
264+ mod = modBigInt
265+
266+-- --------------------------------------------------------------------- [ Int ]
267+
268+divInt : Int -> Int -> Int
269+divInt = prim__sdivInt
270+
271+modInt : Int -> Int -> Int
272+modInt = prim__sremInt
273+
274+instance Integral Int where
275+ div = divInt
276+ mod = modInt
277+
278+-- ------------------------------------------------------------------- [ Bits8 ]
279+divB8 : Bits8 -> Bits8 -> Bits8
280+divB8 = prim__sdivB8
281+
282+modB8 : Bits8 -> Bits8 -> Bits8
283+modB8 = prim__sremB8
284+
285+instance Integral Bits8 where
286+ div = divB8
287+ mod = modB8
288+
289+-- ------------------------------------------------------------------ [ Bits16 ]
290+divB16 : Bits16 -> Bits16 -> Bits16
291+divB16 = prim__sdivB16
292+
293+modB16 : Bits16 -> Bits16 -> Bits16
294+modB16 = prim__sremB16
295+
296+instance Integral Bits16 where
297+ div = divB16
298+ mod = modB16
299+
300+-- ------------------------------------------------------------------ [ Bits32 ]
301+divB32 : Bits32 -> Bits32 -> Bits32
302+divB32 = prim__sdivB32
303+
304+modB32 : Bits32 -> Bits32 -> Bits32
305+modB32 = prim__sremB32
306+
307+instance Integral Bits32 where
308+ div = divB32
309+ mod = modB32
310+
311+-- ------------------------------------------------------------------ [ Bits64 ]
312+divB64 : Bits64 -> Bits64 -> Bits64
313+divB64 = prim__sdivB64
314+
315+modB64 : Bits64 -> Bits64 -> Bits64
316+modB64 = prim__sremB64
317+
318+instance Integral Bits64 where
319+ div = divB64
320+ mod = modB64
321+
322+
libs/prelude/Prelude/Fin.idr+1−1
@@ -55,7 +55,7 @@ natToFin (S k) (S j) with (natToFin k j)
55natToFin _ _ = Nothing
55natToFin _ _ = Nothing
56
56
57integerToFin : Integer -> (n : Nat) -> Maybe (Fin n)
57integerToFin : Integer -> (n : Nat) -> Maybe (Fin n)
58−integerToFin x = natToFin (cast x)
58+integerToFin x n = if x >= 0 then natToFin (cast x) n else Nothing
59
59
60data IsJust : Maybe a -> Type where
60data IsJust : Maybe a -> Type where
61 ItIsJust : IsJust {a} (Just x)
61 ItIsJust : IsJust {a} (Just x)
libs/prelude/Prelude/List.idr+25−35
@@ -35,42 +35,38 @@ isCons (x::xs) = True
35-- Indexing into lists
35-- Indexing into lists
36--------------------------------------------------------------------------------
36--------------------------------------------------------------------------------
37
37
38−%assert_total
39head : (l : List a) -> (isCons l = True) -> a
38head : (l : List a) -> (isCons l = True) -> a
39+head [] refl impossible
40−head (x::xs) p = x
40+head (x::xs) p = x
41
41
42head' : (l : List a) -> Maybe a
42head' : (l : List a) -> Maybe a
43head' [] = Nothing
43head' [] = Nothing
44head' (x::xs) = Just x
44head' (x::xs) = Just x
45
45
46−%assert_total
47tail : (l : List a) -> (isCons l = True) -> List a
46tail : (l : List a) -> (isCons l = True) -> List a
47+tail [] refl impossible
48−tail (x::xs) p = xs
48+tail (x::xs) p = xs
49
49
50tail' : (l : List a) -> Maybe (List a)
50tail' : (l : List a) -> Maybe (List a)
51tail' [] = Nothing
51tail' [] = Nothing
52tail' (x::xs) = Just xs
52tail' (x::xs) = Just xs
53
53
54−%assert_total
55last : (l : List a) -> (isCons l = True) -> a
54last : (l : List a) -> (isCons l = True) -> a
56−last (x::xs) p =
55+last [] refl impossible
57− case xs of
56+last [x] p = x
58− [] => x
59− y::ys => last (y::ys) ?lastProof
57+last (x::y::ys) p = last (y::ys) refl
60
58
61last' : (l : List a) -> Maybe a
59last' : (l : List a) -> Maybe a
62last' [] = Nothing
60last' [] = Nothing
63−last' (x::xs) =
61+last' (x::xs) =
64 case xs of
62 case xs of
65− [] => Just x
63+ [] => Just x
66− y::ys => last' xs
64+ y :: ys => last' xs
67
65
68−%assert_total
69init : (l : List a) -> (isCons l = True) -> List a
66init : (l : List a) -> (isCons l = True) -> List a
70−init (x::xs) p =
67+init [] refl impossible
71− case xs of
72− [] => []
68+init [x] p = []
73− y::ys => x :: init (y::ys) ?initProof
69+init (x::y::ys) p = x :: init (y::ys) refl
74
70
75init' : (l : List a) -> Maybe (List a)
71init' : (l : List a) -> Maybe (List a)
76init' [] = Nothing
72init' [] = Nothing
@@ -175,17 +171,21 @@ instance Functor List where
175-- Zips and unzips
171-- Zips and unzips
176--------------------------------------------------------------------------------
172--------------------------------------------------------------------------------
177
173
178−%assert_total
179zipWith : (f : a -> b -> c) -> (l : List a) -> (r : List b) ->
174zipWith : (f : a -> b -> c) -> (l : List a) -> (r : List b) ->
180 (length l = length r) -> List c
175 (length l = length r) -> List c
181−zipWith f [] [] p = []
176+zipWith f [] (y::ys) refl impossible
177+zipWith f (x::xs) [] refl impossible
178+zipWith f [] [] p = []
182−zipWith f (x::xs) (y::ys) p = f x y :: (zipWith f xs ys ?zipWithTailProof)
179+zipWith f (x::xs) (y::ys) p = f x y :: (zipWith f xs ys ?zipWithTailProof)
183
180
184−%assert_total
185zipWith3 : (f : a -> b -> c -> d) -> (x : List a) -> (y : List b) ->
181zipWith3 : (f : a -> b -> c -> d) -> (x : List a) -> (y : List b) ->
186 (z : List c) -> (length x = length y) -> (length y = length z) -> List d
182 (z : List c) -> (length x = length y) -> (length y = length z) -> List d
187−zipWith3 f [] [] [] refl refl = []
183+zipWith3 f _ [] (z::zs) p refl impossible
184+zipWith3 f _ (y::ys) [] p refl impossible
185+zipWith3 f [] (y::ys) _ refl q impossible
186+zipWith3 f (x::xs) [] _ refl q impossible
187+zipWith3 f [] [] [] p q = []
188−zipWith3 f (x::xs) (y::ys) (z::zs) p q =
188+zipWith3 f (x::xs) (y::ys) (z::zs) p q =
189 f x y z :: (zipWith3 f xs ys zs ?zipWith3TailProof ?zipWith3TailProof')
189 f x y z :: (zipWith3 f xs ys zs ?zipWith3TailProof ?zipWith3TailProof')
190
190
191zip : (l : List a) -> (r : List b) -> (length l = length r) -> List (a, b)
191zip : (l : List a) -> (r : List b) -> (length l = length r) -> List (a, b)
@@ -306,7 +306,7 @@ find p (x::xs) =
306findIndex : (a -> Bool) -> List a -> Maybe Nat
306findIndex : (a -> Bool) -> List a -> Maybe Nat
307findIndex = findIndex' Z
307findIndex = findIndex' Z
308 where
308 where
309−-- findIndex' : Nat -> (a -> Bool) -> List a -> Maybe Nat
309+ findIndex' : Nat -> (a -> Bool) -> List a -> Maybe Nat
310 findIndex' cnt p [] = Nothing
310 findIndex' cnt p [] = Nothing
311 findIndex' cnt p (x::xs) =
311 findIndex' cnt p (x::xs) =
312 if p x then
312 if p x then
@@ -317,7 +317,7 @@ findIndex = findIndex' Z
317findIndices : (a -> Bool) -> List a -> List Nat
317findIndices : (a -> Bool) -> List a -> List Nat
318findIndices = findIndices' Z
318findIndices = findIndices' Z
319 where
319 where
320−-- findIndices' : Nat -> (a -> Bool) -> List a -> List Nat
320+ findIndices' : Nat -> (a -> Bool) -> List a -> List Nat
321 findIndices' cnt p [] = []
321 findIndices' cnt p [] = []
322 findIndices' cnt p (x::xs) =
322 findIndices' cnt p (x::xs) =
323 if p x then
323 if p x then
@@ -562,16 +562,6 @@ hasAnyByNilFalseStepCase = proof {
562 trivial;
562 trivial;
563}
563}
564
564
565−initProof = proof {
566− intros;
567− trivial;
568−}
569−
570−lastProof = proof {
571− intros;
572− trivial;
573−}
574−
575appendNilRightNeutralStepCase = proof {
565appendNilRightNeutralStepCase = proof {
576 intros;
566 intros;
577 rewrite inductiveHypothesis;
567 rewrite inductiveHypothesis;
libs/prelude/Prelude/Nat.idr+15−9
@@ -227,9 +227,10 @@ fact (S n) = (S n) * fact n
227-- Division and modulus
227-- Division and modulus
228--------------------------------------------------------------------------------
228--------------------------------------------------------------------------------
229
229
230+total
230−total mod : Nat -> Nat -> Nat
231+modNat : Nat -> Nat -> Nat
231−mod left Z = left
232+modNat left Z = left
232−mod left (S right) = mod' left left right
233+modNat left (S right) = mod' left left right
233 where
234 where
234 total mod' : Nat -> Nat -> Nat -> Nat
235 total mod' : Nat -> Nat -> Nat -> Nat
235 mod' Z centre right = centre
236 mod' Z centre right = centre
@@ -239,9 +240,10 @@ mod left (S right) = mod' left left right
239 else
240 else
240 mod' left (centre - (S right)) right
241 mod' left (centre - (S right)) right
241
242
243+total
242−total div : Nat -> Nat -> Nat
244+divNat : Nat -> Nat -> Nat
243−div left Z = S left -- div by zero
245+divNat left Z = S left -- div by zero
244−div left (S right) = div' left left right
246+divNat left (S right) = div' left left right
245 where
247 where
246 total div' : Nat -> Nat -> Nat -> Nat
248 total div' : Nat -> Nat -> Nat -> Nat
247 div' Z centre right = Z
249 div' Z centre right = Z
@@ -251,11 +253,15 @@ div left (S right) = div' left left right
251 else
253 else
252 S (div' left (centre - (S right)) right)
254 S (div' left (centre - (S right)) right)
253
255
256+instance Integral Nat where
257+ div = divNat
258+ mod = modNat
259+
254%assert_total
260%assert_total
255log2 : Nat -> Nat
261log2 : Nat -> Nat
256log2 Z = Z
262log2 Z = Z
257log2 (S Z) = Z
263log2 (S Z) = Z
258−log2 n = S (log2 (n `div` 2))
264+log2 n = S (log2 (n `divNat` 2))
259
265
260--------------------------------------------------------------------------------
266--------------------------------------------------------------------------------
261-- GCD and LCM
267-- GCD and LCM
@@ -263,12 +269,12 @@ log2 n = S (log2 (n `div` 2))
263%assert_total
269%assert_total
264gcd : Nat -> Nat -> Nat
270gcd : Nat -> Nat -> Nat
265gcd a Z = a
271gcd a Z = a
266−gcd a b = gcd b (a `mod` b)
272+gcd a b = gcd b (a `modNat` b)
267
273
268total lcm : Nat -> Nat -> Nat
274total lcm : Nat -> Nat -> Nat
269lcm _ Z = Z
275lcm _ Z = Z
270lcm Z _ = Z
276lcm Z _ = Z
271−lcm x y = div (x * y) (gcd x y)
277+lcm x y = divNat (x * y) (gcd x y)
272
278
273--------------------------------------------------------------------------------
279--------------------------------------------------------------------------------
274-- Properties
280-- Properties
rts/Makefile+3−3
@@ -1,11 +1,11 @@
1include ../config.mk
1include ../config.mk
2
2
3OBJS = idris_rts.o idris_heap.o idris_gc.o idris_gmp.o idris_stdfgn.o \
3OBJS = idris_rts.o idris_heap.o idris_gc.o idris_gmp.o idris_stdfgn.o \
4− idris_bitstring.o idris_opts.o idris_stats.o
4+ idris_bitstring.o idris_opts.o idris_stats.o mini-gmp.o
5HDRS = idris_rts.h idris_heap.h idris_gc.h idris_gmp.h idris_stdfgn.h \
5HDRS = idris_rts.h idris_heap.h idris_gc.h idris_gmp.h idris_stdfgn.h \
6− idris_bitstring.h idris_opts.h idris_stats.h
6+ idris_bitstring.h idris_opts.h idris_stats.h mini-gmp.h
7CFLAGS:=-fPIC $(CFLAGS)
7CFLAGS:=-fPIC $(CFLAGS)
8−CFLAGS += $(GMP_INCLUDE_DIR)
8+CFLAGS += $(GMP_INCLUDE_DIR) $(GMP)
9
9
10LIBTARGET = libidris_rts.a
10LIBTARGET = libidris_rts.a
11
11
rts/idris_gc.c+8−1
@@ -24,6 +24,9 @@ VAL copy(VM* vm, VAL x) {
24 case STRING:
24 case STRING:
25 cl = MKSTRc(vm, x->info.str);
25 cl = MKSTRc(vm, x->info.str);
26 break;
26 break;
27+ case STROFFSET:
28+ cl = MKSTROFFc(vm, x->info.str_offset);
29+ break;
27 case BIGINT:
30 case BIGINT:
28 cl = MKBIGMc(vm, x->info.ptr);
31 cl = MKBIGMc(vm, x->info.ptr);
29 break;
32 break;
@@ -60,7 +63,7 @@ void cheney(VM *vm) {
60 while(scan < vm->heap.next) {
63 while(scan < vm->heap.next) {
61 size_t inc = *((size_t*)scan);
64 size_t inc = *((size_t*)scan);
62 VAL heap_item = (VAL)(scan+sizeof(size_t));
65 VAL heap_item = (VAL)(scan+sizeof(size_t));
63− // If it's a CON, copy its arguments
66+ // If it's a CON or STROFFSET, copy its arguments
64 switch(GETTY(heap_item)) {
67 switch(GETTY(heap_item)) {
65 case CON:
68 case CON:
66 ar = ARITY(heap_item);
69 ar = ARITY(heap_item);
@@ -71,6 +74,10 @@ void cheney(VM *vm) {
71 heap_item->info.c.args[i] = newptr;
74 heap_item->info.c.args[i] = newptr;
72 }
75 }
73 break;
76 break;
77+ case STROFFSET:
78+ heap_item->info.str_offset->str
79+ = copy(vm, heap_item->info.str_offset->str);
80+ break;
74 default: // Nothing to copy
81 default: // Nothing to copy
75 break;
82 break;
76 }
83 }
rts/idris_gmp.c+5−1
@@ -1,5 +1,9 @@
1#include "idris_rts.h"
1#include "idris_rts.h"
2+#ifdef IDRIS_GMP
2−#include <gmp.h>
3+#include <gmp.h>
4+#else
5+#include "mini-gmp.h"
6+#endif
3#include <stdlib.h>
7#include <stdlib.h>
4#include <string.h>
8#include <string.h>
5
9
rts/idris_gmp.h+4
@@ -1,7 +1,11 @@
1#ifndef _IDRISGMP_H
1#ifndef _IDRISGMP_H
2#define _IDRISGMP_H
2#define _IDRISGMP_H
3
3
4+#ifdef IDRIS_GMP
4#include <gmp.h>
5#include <gmp.h>
6+#else
7+#include "mini-gmp.h"
8+#endif
5
9
6VAL MKBIGI(int val);
10VAL MKBIGI(int val);
7VAL MKBIGC(VM* vm, char* bigint);
11VAL MKBIGC(VM* vm, char* bigint);
rts/idris_rts.c+44−1
@@ -84,6 +84,10 @@ void idris_doneAlloc(VM* vm) {
84 }
84 }
85}
85}
86
86
87+int space(VM* vm, size_t size) {
88+ return (vm->heap.next + size + sizeof(size_t) < vm->heap.end);
89+}
90+
87void* allocate(VM* vm, size_t size, int outerlock) {
91void* allocate(VM* vm, size_t size, int outerlock) {
88// return malloc(size);
92// return malloc(size);
89 int lock = vm->processes > 0 && !outerlock;
93 int lock = vm->processes > 0 && !outerlock;
@@ -161,6 +165,12 @@ VAL MKSTR(VM* vm, const char* str) {
161 return cl;
165 return cl;
162}
166}
163
167
168+char* GETSTROFF(VAL stroff) {
169+ // Assume STROFF
170+ StrOffset* root = stroff->info.str_offset;
171+ return (root->str->info.str + root->offset);
172+}
173+
164VAL MKPTR(VM* vm, void* ptr) {
174VAL MKPTR(VM* vm, void* ptr) {
165 Closure* cl = allocate(vm, sizeof(Closure), 0);
175 Closure* cl = allocate(vm, sizeof(Closure), 0);
166 SETTY(cl, PTR);
176 SETTY(cl, PTR);
@@ -397,8 +407,41 @@ VAL idris_strHead(VM* vm, VAL str) {
397 return MKINT((i_int)(GETSTR(str)[0]));
407 return MKINT((i_int)(GETSTR(str)[0]));
398}
408}
399
409
410+VAL MKSTROFFc(VM* vm, StrOffset* off) {
411+ Closure* cl = allocate(vm, sizeof(Closure) + sizeof(StrOffset), 1);
412+ SETTY(cl, STROFFSET);
413+ cl->info.str_offset = (StrOffset*)((char*)cl + sizeof(Closure));
414+
415+ cl->info.str_offset->str = off->str;
416+ cl->info.str_offset->offset = off->offset;
417+
418+ return cl;
419+}
420+
400VAL idris_strTail(VM* vm, VAL str) {
421VAL idris_strTail(VM* vm, VAL str) {
422+ // If there's no room, just copy the string, or we'll have a problem after
423+ // gc moves str
424+ if (space(vm, sizeof(Closure) + sizeof(StrOffset))) {
425+ Closure* cl = allocate(vm, sizeof(Closure) + sizeof(StrOffset), 0);
426+ SETTY(cl, STROFFSET);
427+ cl->info.str_offset = (StrOffset*)((char*)cl + sizeof(Closure));
428+
429+ int offset = 0;
430+ VAL root = str;
431+
432+ while(root!=NULL && !ISSTR(root)) { // find the root, carry on.
433+ // In theory, at most one step here!
434+ offset += root->info.str_offset->offset;
435+ root = root->info.str_offset->str;
436+ }
437+
438+ cl->info.str_offset->str = root;
439+ cl->info.str_offset->offset = offset+1;
440+
441+ return cl;
442+ } else {
401− return MKSTR(vm, GETSTR(str)+1);
443+ return MKSTR(vm, GETSTR(str)+1);
444+ }
402}
445}
403
446
404VAL idris_strCons(VM* vm, VAL x, VAL xs) {
447VAL idris_strCons(VM* vm, VAL x, VAL xs) {
rts/idris_rts.h+13−2
@@ -15,7 +15,8 @@
15// Closures
15// Closures
16
16
17typedef enum {
17typedef enum {
18+ CON, INT, BIGINT, FLOAT, STRING, STROFFSET,
18− CON, INT, BIGINT, FLOAT, STRING, BITS8, BITS16, BITS32, BITS64, UNIT, PTR, FWD
19+ BITS8, BITS16, BITS32, BITS64, UNIT, PTR, FWD
19} ClosureType;
20} ClosureType;
20
21
21typedef struct Closure *VAL;
22typedef struct Closure *VAL;
@@ -25,6 +26,11 @@ typedef struct {
25 VAL args[];
26 VAL args[];
26} con;
27} con;
27
28
29+typedef struct {
30+ VAL str;
31+ int offset;
32+} StrOffset;
33+
28typedef struct Closure {
34typedef struct Closure {
29// Use top 16 bits of ty for saying which heap value is in
35// Use top 16 bits of ty for saying which heap value is in
30// Bottom 16 bits for closure type
36// Bottom 16 bits for closure type
@@ -34,6 +40,7 @@ typedef struct Closure {
34 int i;
40 int i;
35 double f;
41 double f;
36 char* str;
42 char* str;
43+ StrOffset* str_offset;
37 void* ptr;
44 void* ptr;
38 uint8_t bits8;
45 uint8_t bits8;
39 uint16_t bits16;
46 uint16_t bits16;
@@ -92,7 +99,7 @@ typedef void(*func)(VM*, VAL*);
92
99
93// Retrieving values
100// Retrieving values
94
101
95−#define GETSTR(x) (((VAL)(x))->info.str)
102+#define GETSTR(x) (ISSTR(x) ? (((VAL)(x))->info.str) : GETSTROFF(x))
96#define GETPTR(x) (((VAL)(x))->info.ptr)
103#define GETPTR(x) (((VAL)(x))->info.ptr)
97#define GETFLOAT(x) (((VAL)(x))->info.f)
104#define GETFLOAT(x) (((VAL)(x))->info.f)
98
105
@@ -119,6 +126,7 @@ typedef intptr_t i_int;
119#define MKINT(x) ((void*)((x)<<1)+1)
126#define MKINT(x) ((void*)((x)<<1)+1)
120#define GETINT(x) ((i_int)(x)>>1)
127#define GETINT(x) ((i_int)(x)>>1)
121#define ISINT(x) ((((i_int)x)&1) == 1)
128#define ISINT(x) ((((i_int)x)&1) == 1)
129+#define ISSTR(x) (((VAL)(x))->ty == STRING)
122
130
123#define INTOP(op,x,y) MKINT((i_int)((((i_int)x)>>1) op (((i_int)y)>>1)))
131#define INTOP(op,x,y) MKINT((i_int)((((i_int)x)>>1) op (((i_int)y)>>1)))
124#define UINTOP(op,x,y) MKINT((i_int)((((uintptr_t)x)>>1) op (((uintptr_t)y)>>1)))
132#define UINTOP(op,x,y) MKINT((i_int)((((uintptr_t)x)>>1) op (((uintptr_t)y)>>1)))
@@ -151,9 +159,12 @@ VAL MKB64(VM* vm, uint64_t b);
151
159
152// following versions don't take a lock when allocating
160// following versions don't take a lock when allocating
153VAL MKFLOATc(VM* vm, double val);
161VAL MKFLOATc(VM* vm, double val);
162+VAL MKSTROFFc(VM* vm, StrOffset* off);
154VAL MKSTRc(VM* vm, char* str);
163VAL MKSTRc(VM* vm, char* str);
155VAL MKPTRc(VM* vm, void* ptr);
164VAL MKPTRc(VM* vm, void* ptr);
156
165
166+char* GETSTROFF(VAL stroff);
167+
157// #define SETTAG(x, a) (x)->info.c.tag = (a)
168// #define SETTAG(x, a) (x)->info.c.tag = (a)
158#define SETARG(x, i, a) ((x)->info.c.args)[i] = ((VAL)(a))
169#define SETARG(x, i, a) ((x)->info.c.args)[i] = ((VAL)(a))
159#define GETARG(x, i) ((x)->info.c.args)[i]
170#define GETARG(x, i) ((x)->info.c.args)[i]
rts/mini-gmp.cnew file+4120
@@ -0,0 +1,4120 @@
1+/* mini-gmp, a minimalistic implementation of a GNU GMP subset.
2+
3+ Contributed to the GNU project by Niels Möller
4+
5+Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001,
6+2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
7+Free Software Foundation, Inc.
8+
9+This file is part of the GNU MP Library.
10+
11+The GNU MP Library is free software; you can redistribute it and/or modify
12+it under the terms of the GNU Lesser General Public License as published by
13+the Free Software Foundation; either version 3 of the License, or (at your
14+option) any later version.
15+
16+The GNU MP Library is distributed in the hope that it will be useful, but
17+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
19+License for more details.
20+
21+You should have received a copy of the GNU Lesser General Public License
22+along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
23+
24+/* NOTE: All functions in this file which are not declared in
25+ mini-gmp.h are internal, and are not intended to be compatible
26+ neither with GMP nor with future versions of mini-gmp. */
27+
28+/* Much of the material copied from GMP files, including: gmp-impl.h,
29+ longlong.h, mpn/generic/add_n.c, mpn/generic/addmul_1.c,
30+ mpn/generic/lshift.c, mpn/generic/mul_1.c,
31+ mpn/generic/mul_basecase.c, mpn/generic/rshift.c,
32+ mpn/generic/sbpi1_div_qr.c, mpn/generic/sub_n.c,
33+ mpn/generic/submul_1.c. */
34+
35+#include <assert.h>
36+#include <ctype.h>
37+#include <limits.h>
38+#include <stdio.h>
39+#include <stdlib.h>
40+#include <string.h>
41+
42+#include "mini-gmp.h"
43+
44+
45+/* Macros */
46+#define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT)
47+
48+#define GMP_LIMB_MAX (~ (mp_limb_t) 0)
49+#define GMP_LIMB_HIGHBIT ((mp_limb_t) 1 << (GMP_LIMB_BITS - 1))
50+
51+#define GMP_HLIMB_BIT ((mp_limb_t) 1 << (GMP_LIMB_BITS / 2))
52+#define GMP_LLIMB_MASK (GMP_HLIMB_BIT - 1)
53+
54+#define GMP_ULONG_BITS (sizeof(unsigned long) * CHAR_BIT)
55+#define GMP_ULONG_HIGHBIT ((unsigned long) 1 << (GMP_ULONG_BITS - 1))
56+
57+#define GMP_ABS(x) ((x) >= 0 ? (x) : -(x))
58+#define GMP_NEG_CAST(T,x) (-((T)((x) + 1) - 1))
59+
60+#define GMP_MIN(a, b) ((a) < (b) ? (a) : (b))
61+#define GMP_MAX(a, b) ((a) > (b) ? (a) : (b))
62+
63+#define gmp_assert_nocarry(x) do { \
64+ mp_limb_t __cy = x; \
65+ assert (__cy == 0); \
66+ } while (0)
67+
68+#define gmp_clz(count, x) do { \
69+ mp_limb_t __clz_x = (x); \
70+ unsigned __clz_c; \
71+ for (__clz_c = 0; \
72+ (__clz_x & ((mp_limb_t) 0xff << (GMP_LIMB_BITS - 8))) == 0; \
73+ __clz_c += 8) \
74+ __clz_x <<= 8; \
75+ for (; (__clz_x & GMP_LIMB_HIGHBIT) == 0; __clz_c++) \
76+ __clz_x <<= 1; \
77+ (count) = __clz_c; \
78+ } while (0)
79+
80+#define gmp_ctz(count, x) do { \
81+ mp_limb_t __ctz_x = (x); \
82+ unsigned __ctz_c = 0; \
83+ gmp_clz (__ctz_c, __ctz_x & - __ctz_x); \
84+ (count) = GMP_LIMB_BITS - 1 - __ctz_c; \
85+ } while (0)
86+
87+#define gmp_add_ssaaaa(sh, sl, ah, al, bh, bl) \
88+ do { \
89+ mp_limb_t __x; \
90+ __x = (al) + (bl); \
91+ (sh) = (ah) + (bh) + (__x < (al)); \
92+ (sl) = __x; \
93+ } while (0)
94+
95+#define gmp_sub_ddmmss(sh, sl, ah, al, bh, bl) \
96+ do { \
97+ mp_limb_t __x; \
98+ __x = (al) - (bl); \
99+ (sh) = (ah) - (bh) - ((al) < (bl)); \
100+ (sl) = __x; \
101+ } while (0)
102+
103+#define gmp_umul_ppmm(w1, w0, u, v) \
104+ do { \
105+ mp_limb_t __x0, __x1, __x2, __x3; \
106+ unsigned __ul, __vl, __uh, __vh; \
107+ mp_limb_t __u = (u), __v = (v); \
108+ \
109+ __ul = __u & GMP_LLIMB_MASK; \
110+ __uh = __u >> (GMP_LIMB_BITS / 2); \
111+ __vl = __v & GMP_LLIMB_MASK; \
112+ __vh = __v >> (GMP_LIMB_BITS / 2); \
113+ \
114+ __x0 = (mp_limb_t) __ul * __vl; \
115+ __x1 = (mp_limb_t) __ul * __vh; \
116+ __x2 = (mp_limb_t) __uh * __vl; \
117+ __x3 = (mp_limb_t) __uh * __vh; \
118+ \
119+ __x1 += __x0 >> (GMP_LIMB_BITS / 2);/* this can't give carry */ \
120+ __x1 += __x2; /* but this indeed can */ \
121+ if (__x1 < __x2) /* did we get it? */ \
122+ __x3 += GMP_HLIMB_BIT; /* yes, add it in the proper pos. */ \
123+ \
124+ (w1) = __x3 + (__x1 >> (GMP_LIMB_BITS / 2)); \
125+ (w0) = (__x1 << (GMP_LIMB_BITS / 2)) + (__x0 & GMP_LLIMB_MASK); \
126+ } while (0)
127+
128+#define gmp_udiv_qrnnd_preinv(q, r, nh, nl, d, di) \
129+ do { \
130+ mp_limb_t _qh, _ql, _r, _mask; \
131+ gmp_umul_ppmm (_qh, _ql, (nh), (di)); \
132+ gmp_add_ssaaaa (_qh, _ql, _qh, _ql, (nh) + 1, (nl)); \
133+ _r = (nl) - _qh * (d); \
134+ _mask = -(mp_limb_t) (_r > _ql); /* both > and >= are OK */ \
135+ _qh += _mask; \
136+ _r += _mask & (d); \
137+ if (_r >= (d)) \
138+ { \
139+ _r -= (d); \
140+ _qh++; \
141+ } \
142+ \
143+ (r) = _r; \
144+ (q) = _qh; \
145+ } while (0)
146+
147+#define gmp_udiv_qr_3by2(q, r1, r0, n2, n1, n0, d1, d0, dinv) \
148+ do { \
149+ mp_limb_t _q0, _t1, _t0, _mask; \
150+ gmp_umul_ppmm ((q), _q0, (n2), (dinv)); \
151+ gmp_add_ssaaaa ((q), _q0, (q), _q0, (n2), (n1)); \
152+ \
153+ /* Compute the two most significant limbs of n - q'd */ \
154+ (r1) = (n1) - (d1) * (q); \
155+ gmp_sub_ddmmss ((r1), (r0), (r1), (n0), (d1), (d0)); \
156+ gmp_umul_ppmm (_t1, _t0, (d0), (q)); \
157+ gmp_sub_ddmmss ((r1), (r0), (r1), (r0), _t1, _t0); \
158+ (q)++; \
159+ \
160+ /* Conditionally adjust q and the remainders */ \
161+ _mask = - (mp_limb_t) ((r1) >= _q0); \
162+ (q) += _mask; \
163+ gmp_add_ssaaaa ((r1), (r0), (r1), (r0), _mask & (d1), _mask & (d0)); \
164+ if ((r1) >= (d1)) \
165+ { \
166+ if ((r1) > (d1) || (r0) >= (d0)) \
167+ { \
168+ (q)++; \
169+ gmp_sub_ddmmss ((r1), (r0), (r1), (r0), (d1), (d0)); \
170+ } \
171+ } \
172+ } while (0)
173+
174+/* Swap macros. */
175+#define MP_LIMB_T_SWAP(x, y) \
176+ do { \
177+ mp_limb_t __mp_limb_t_swap__tmp = (x); \
178+ (x) = (y); \
179+ (y) = __mp_limb_t_swap__tmp; \
180+ } while (0)
181+#define MP_SIZE_T_SWAP(x, y) \
182+ do { \
183+ mp_size_t __mp_size_t_swap__tmp = (x); \
184+ (x) = (y); \
185+ (y) = __mp_size_t_swap__tmp; \
186+ } while (0)
187+#define MP_BITCNT_T_SWAP(x,y) \
188+ do { \
189+ mp_bitcnt_t __mp_bitcnt_t_swap__tmp = (x); \
190+ (x) = (y); \
191+ (y) = __mp_bitcnt_t_swap__tmp; \
192+ } while (0)
193+#define MP_PTR_SWAP(x, y) \
194+ do { \
195+ mp_ptr __mp_ptr_swap__tmp = (x); \
196+ (x) = (y); \
197+ (y) = __mp_ptr_swap__tmp; \
198+ } while (0)
199+#define MP_SRCPTR_SWAP(x, y) \
200+ do { \
201+ mp_srcptr __mp_srcptr_swap__tmp = (x); \
202+ (x) = (y); \
203+ (y) = __mp_srcptr_swap__tmp; \
204+ } while (0)
205+
206+#define MPN_PTR_SWAP(xp,xs, yp,ys) \
207+ do { \
208+ MP_PTR_SWAP (xp, yp); \
209+ MP_SIZE_T_SWAP (xs, ys); \
210+ } while(0)
211+#define MPN_SRCPTR_SWAP(xp,xs, yp,ys) \
212+ do { \
213+ MP_SRCPTR_SWAP (xp, yp); \
214+ MP_SIZE_T_SWAP (xs, ys); \
215+ } while(0)
216+
217+#define MPZ_PTR_SWAP(x, y) \
218+ do { \
219+ mpz_ptr __mpz_ptr_swap__tmp = (x); \
220+ (x) = (y); \
221+ (y) = __mpz_ptr_swap__tmp; \
222+ } while (0)
223+#define MPZ_SRCPTR_SWAP(x, y) \
224+ do { \
225+ mpz_srcptr __mpz_srcptr_swap__tmp = (x); \
226+ (x) = (y); \
227+ (y) = __mpz_srcptr_swap__tmp; \
228+ } while (0)
229+
230+
231+/* Memory allocation and other helper functions. */
232+static void
233+gmp_die (const char *msg)
234+{
235+ fprintf (stderr, "%s\n", msg);
236+ abort();
237+}
238+
239+static void *
240+gmp_default_alloc (size_t size)
241+{
242+ void *p;
243+
244+ assert (size > 0);
245+
246+ p = malloc (size);
247+ if (!p)
248+ gmp_die("gmp_default_alloc: Virtual memory exhausted.");
249+
250+ return p;
251+}
252+
253+static void *
254+gmp_default_realloc (void *old, size_t old_size, size_t new_size)
255+{
256+ mp_ptr p;
257+
258+ p = realloc (old, new_size);
259+
260+ if (!p)
261+ gmp_die("gmp_default_realoc: Virtual memory exhausted.");
262+
263+ return p;
264+}
265+
266+static void
267+gmp_default_free (void *p, size_t size)
268+{
269+ free (p);
270+}
271+
272+static void * (*gmp_allocate_func) (size_t) = gmp_default_alloc;
273+static void * (*gmp_reallocate_func) (void *, size_t, size_t) = gmp_default_realloc;
274+static void (*gmp_free_func) (void *, size_t) = gmp_default_free;
275+
276+void
277+mp_get_memory_functions (void *(**alloc_func) (size_t),
278+ void *(**realloc_func) (void *, size_t, size_t),
279+ void (**free_func) (void *, size_t))
280+{
281+ if (alloc_func)
282+ *alloc_func = gmp_allocate_func;
283+
284+ if (realloc_func)
285+ *realloc_func = gmp_reallocate_func;
286+
287+ if (free_func)
288+ *free_func = gmp_free_func;
289+}
290+
291+void
292+mp_set_memory_functions (void *(*alloc_func) (size_t),
293+ void *(*realloc_func) (void *, size_t, size_t),
294+ void (*free_func) (void *, size_t))
295+{
296+ if (!alloc_func)
297+ alloc_func = gmp_default_alloc;
298+ if (!realloc_func)
299+ realloc_func = gmp_default_realloc;
300+ if (!free_func)
301+ free_func = gmp_default_free;
302+
303+ gmp_allocate_func = alloc_func;
304+ gmp_reallocate_func = realloc_func;
305+ gmp_free_func = free_func;
306+}
307+
308+#define gmp_xalloc(size) ((*gmp_allocate_func)((size)))
309+#define gmp_free(p) ((*gmp_free_func) ((p), 0))
310+
311+static mp_ptr
312+gmp_xalloc_limbs (mp_size_t size)
313+{
314+ return gmp_xalloc (size * sizeof (mp_limb_t));
315+}
316+
317+static mp_ptr
318+gmp_xrealloc_limbs (mp_ptr old, mp_size_t size)
319+{
320+ assert (size > 0);
321+ return (*gmp_reallocate_func) (old, 0, size * sizeof (mp_limb_t));
322+}
323+
324+
325+/* MPN interface */
326+
327+void
328+mpn_copyi (mp_ptr d, mp_srcptr s, mp_size_t n)
329+{
330+ mp_size_t i;
331+ for (i = 0; i < n; i++)
332+ d[i] = s[i];
333+}
334+
335+void
336+mpn_copyd (mp_ptr d, mp_srcptr s, mp_size_t n)
337+{
338+ while (n-- > 0)
339+ d[n] = s[n];
340+}
341+
342+int
343+mpn_cmp (mp_srcptr ap, mp_srcptr bp, mp_size_t n)
344+{
345+ while (--n >= 0)
346+ {
347+ if (ap[n] != bp[n])
348+ return ap[n] > bp[n] ? 1 : -1;
349+ }
350+ return 0;
351+}
352+
353+static int
354+mpn_cmp4 (mp_srcptr ap, mp_size_t an, mp_srcptr bp, mp_size_t bn)
355+{
356+ if (an != bn)
357+ return an < bn ? -1 : 1;
358+ else
359+ return mpn_cmp (ap, bp, an);
360+}
361+
362+static mp_size_t
363+mpn_normalized_size (mp_srcptr xp, mp_size_t n)
364+{
365+ for (; n > 0 && xp[n-1] == 0; n--)
366+ ;
367+ return n;
368+}
369+
370+#define mpn_zero_p(xp, n) (mpn_normalized_size ((xp), (n)) == 0)
371+
372+mp_limb_t
373+mpn_add_1 (mp_ptr rp, mp_srcptr ap, mp_size_t n, mp_limb_t b)
374+{
375+ mp_size_t i;
376+
377+ assert (n > 0);
378+ i = 0;
379+ do
380+ {
381+ mp_limb_t r = ap[i] + b;
382+ /* Carry out */
383+ b = (r < b);
384+ rp[i] = r;
385+ }
386+ while (++i < n);
387+
388+ return b;
389+}
390+
391+mp_limb_t
392+mpn_add_n (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t n)
393+{
394+ mp_size_t i;
395+ mp_limb_t cy;
396+
397+ for (i = 0, cy = 0; i < n; i++)
398+ {
399+ mp_limb_t a, b, r;
400+ a = ap[i]; b = bp[i];
401+ r = a + cy;
402+ cy = (r < cy);
403+ r += b;
404+ cy += (r < b);
405+ rp[i] = r;
406+ }
407+ return cy;
408+}
409+
410+mp_limb_t
411+mpn_add (mp_ptr rp, mp_srcptr ap, mp_size_t an, mp_srcptr bp, mp_size_t bn)
412+{
413+ mp_limb_t cy;
414+
415+ assert (an >= bn);
416+
417+ cy = mpn_add_n (rp, ap, bp, bn);
418+ if (an > bn)
419+ cy = mpn_add_1 (rp + bn, ap + bn, an - bn, cy);
420+ return cy;
421+}
422+
423+mp_limb_t
424+mpn_sub_1 (mp_ptr rp, mp_srcptr ap, mp_size_t n, mp_limb_t b)
425+{
426+ mp_size_t i;
427+
428+ assert (n > 0);
429+
430+ i = 0;
431+ do
432+ {
433+ mp_limb_t a = ap[i];
434+ /* Carry out */
435+ mp_limb_t cy = a < b;;
436+ rp[i] = a - b;
437+ b = cy;
438+ }
439+ while (++i < n);
440+
441+ return b;
442+}
443+
444+mp_limb_t
445+mpn_sub_n (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t n)
446+{
447+ mp_size_t i;
448+ mp_limb_t cy;
449+
450+ for (i = 0, cy = 0; i < n; i++)
451+ {
452+ mp_limb_t a, b;
453+ a = ap[i]; b = bp[i];
454+ b += cy;
455+ cy = (b < cy);
456+ cy += (a < b);
457+ rp[i] = a - b;
458+ }
459+ return cy;
460+}
461+
462+mp_limb_t
463+mpn_sub (mp_ptr rp, mp_srcptr ap, mp_size_t an, mp_srcptr bp, mp_size_t bn)
464+{
465+ mp_limb_t cy;
466+
467+ assert (an >= bn);
468+
469+ cy = mpn_sub_n (rp, ap, bp, bn);
470+ if (an > bn)
471+ cy = mpn_sub_1 (rp + bn, ap + bn, an - bn, cy);
472+ return cy;
473+}
474+
475+mp_limb_t
476+mpn_mul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl)
477+{
478+ mp_limb_t ul, cl, hpl, lpl;
479+
480+ assert (n >= 1);
481+
482+ cl = 0;
483+ do
484+ {
485+ ul = *up++;
486+ gmp_umul_ppmm (hpl, lpl, ul, vl);
487+
488+ lpl += cl;
489+ cl = (lpl < cl) + hpl;
490+
491+ *rp++ = lpl;
492+ }
493+ while (--n != 0);
494+
495+ return cl;
496+}
497+
498+mp_limb_t
499+mpn_addmul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl)
500+{
501+ mp_limb_t ul, cl, hpl, lpl, rl;
502+
503+ assert (n >= 1);
504+
505+ cl = 0;
506+ do
507+ {
508+ ul = *up++;
509+ gmp_umul_ppmm (hpl, lpl, ul, vl);
510+
511+ lpl += cl;
512+ cl = (lpl < cl) + hpl;
513+
514+ rl = *rp;
515+ lpl = rl + lpl;
516+ cl += lpl < rl;
517+ *rp++ = lpl;
518+ }
519+ while (--n != 0);
520+
521+ return cl;
522+}
523+
524+mp_limb_t
525+mpn_submul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl)
526+{
527+ mp_limb_t ul, cl, hpl, lpl, rl;
528+
529+ assert (n >= 1);
530+
531+ cl = 0;
532+ do
533+ {
534+ ul = *up++;
535+ gmp_umul_ppmm (hpl, lpl, ul, vl);
536+
537+ lpl += cl;
538+ cl = (lpl < cl) + hpl;
539+
540+ rl = *rp;
541+ lpl = rl - lpl;
542+ cl += lpl > rl;
543+ *rp++ = lpl;
544+ }
545+ while (--n != 0);
546+
547+ return cl;
548+}
549+
550+mp_limb_t
551+mpn_mul (mp_ptr rp, mp_srcptr up, mp_size_t un, mp_srcptr vp, mp_size_t vn)
552+{
553+ assert (un >= vn);
554+ assert (vn >= 1);
555+
556+ /* We first multiply by the low order limb. This result can be
557+ stored, not added, to rp. We also avoid a loop for zeroing this
558+ way. */
559+
560+ rp[un] = mpn_mul_1 (rp, up, un, vp[0]);
561+ rp += 1, vp += 1, vn -= 1;
562+
563+ /* Now accumulate the product of up[] and the next higher limb from
564+ vp[]. */
565+
566+ while (vn >= 1)
567+ {
568+ rp[un] = mpn_addmul_1 (rp, up, un, vp[0]);
569+ rp += 1, vp += 1, vn -= 1;
570+ }
571+ return rp[un - 1];
572+}
573+
574+void
575+mpn_mul_n (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t n)
576+{
577+ mpn_mul (rp, ap, n, bp, n);
578+}
579+
580+void
581+mpn_sqr (mp_ptr rp, mp_srcptr ap, mp_size_t n)
582+{
583+ mpn_mul (rp, ap, n, ap, n);
584+}
585+
586+mp_limb_t
587+mpn_lshift (mp_ptr rp, mp_srcptr up, mp_size_t n, unsigned int cnt)
588+{
589+ mp_limb_t high_limb, low_limb;
590+ unsigned int tnc;
591+ mp_size_t i;
592+ mp_limb_t retval;
593+
594+ assert (n >= 1);
595+ assert (cnt >= 1);
596+ assert (cnt < GMP_LIMB_BITS);
597+
598+ up += n;
599+ rp += n;
600+
601+ tnc = GMP_LIMB_BITS - cnt;
602+ low_limb = *--up;
603+ retval = low_limb >> tnc;
604+ high_limb = (low_limb << cnt);
605+
606+ for (i = n; --i != 0;)
607+ {
608+ low_limb = *--up;
609+ *--rp = high_limb | (low_limb >> tnc);
610+ high_limb = (low_limb << cnt);
611+ }
612+ *--rp = high_limb;
613+
614+ return retval;
615+}
616+
617+mp_limb_t
618+mpn_rshift (mp_ptr rp, mp_srcptr up, mp_size_t n, unsigned int cnt)
619+{
620+ mp_limb_t high_limb, low_limb;
621+ unsigned int tnc;
622+ mp_size_t i;
623+ mp_limb_t retval;
624+
625+ assert (n >= 1);
626+ assert (cnt >= 1);
627+ assert (cnt < GMP_LIMB_BITS);
628+
629+ tnc = GMP_LIMB_BITS - cnt;
630+ high_limb = *up++;
631+ retval = (high_limb << tnc);
632+ low_limb = high_limb >> cnt;
633+
634+ for (i = n; --i != 0;)
635+ {
636+ high_limb = *up++;
637+ *rp++ = low_limb | (high_limb << tnc);
638+ low_limb = high_limb >> cnt;
639+ }
640+ *rp = low_limb;
641+
642+ return retval;
643+}
644+
645+static mp_bitcnt_t
646+mpn_common_scan (mp_limb_t limb, mp_size_t i, mp_srcptr up, mp_size_t un,
647+ mp_limb_t ux)
648+{
649+ unsigned cnt;
650+
651+ assert (ux == 0 || ux == GMP_LIMB_MAX);
652+ assert (0 <= i && i <= un );
653+
654+ while (limb == 0)
655+ {
656+ i++;
657+ if (i == un)
658+ return (ux == 0 ? ~(mp_bitcnt_t) 0 : un * GMP_LIMB_BITS);
659+ limb = ux ^ up[i];
660+ }
661+ gmp_ctz (cnt, limb);
662+ return (mp_bitcnt_t) i * GMP_LIMB_BITS + cnt;
663+}
664+
665+mp_bitcnt_t
666+mpn_scan1 (mp_srcptr ptr, mp_bitcnt_t bit)
667+{
668+ mp_size_t i;
669+ i = bit / GMP_LIMB_BITS;
670+
671+ return mpn_common_scan ( ptr[i] & (GMP_LIMB_MAX << (bit % GMP_LIMB_BITS)),
672+ i, ptr, i, 0);
673+}
674+
675+mp_bitcnt_t
676+mpn_scan0 (mp_srcptr ptr, mp_bitcnt_t bit)
677+{
678+ mp_size_t i;
679+ i = bit / GMP_LIMB_BITS;
680+
681+ return mpn_common_scan (~ptr[i] & (GMP_LIMB_MAX << (bit % GMP_LIMB_BITS)),
682+ i, ptr, i, GMP_LIMB_MAX);
683+}
684+
685+
686+/* MPN division interface. */
687+mp_limb_t
688+mpn_invert_3by2 (mp_limb_t u1, mp_limb_t u0)
689+{
690+ mp_limb_t r, p, m;
691+ unsigned ul, uh;
692+ unsigned ql, qh;
693+
694+ /* First, do a 2/1 inverse. */
695+ /* The inverse m is defined as floor( (B^2 - 1 - u1)/u1 ), so that 0 <
696+ * B^2 - (B + m) u1 <= u1 */
697+ assert (u1 >= GMP_LIMB_HIGHBIT);
698+
699+ ul = u1 & GMP_LLIMB_MASK;
700+ uh = u1 >> (GMP_LIMB_BITS / 2);
701+
702+ qh = ~u1 / uh;
703+ r = ((~u1 - (mp_limb_t) qh * uh) << (GMP_LIMB_BITS / 2)) | GMP_LLIMB_MASK;
704+
705+ p = (mp_limb_t) qh * ul;
706+ /* Adjustment steps taken from udiv_qrnnd_c */
707+ if (r < p)
708+ {
709+ qh--;
710+ r += u1;
711+ if (r >= u1) /* i.e. we didn't get carry when adding to r */
712+ if (r < p)
713+ {
714+ qh--;
715+ r += u1;
716+ }
717+ }
718+ r -= p;
719+
720+ /* Do a 3/2 division (with half limb size) */
721+ p = (r >> (GMP_LIMB_BITS / 2)) * qh + r;
722+ ql = (p >> (GMP_LIMB_BITS / 2)) + 1;
723+
724+ /* By the 3/2 method, we don't need the high half limb. */
725+ r = (r << (GMP_LIMB_BITS / 2)) + GMP_LLIMB_MASK - ql * u1;
726+
727+ if (r >= (p << (GMP_LIMB_BITS / 2)))
728+ {
729+ ql--;
730+ r += u1;
731+ }
732+ m = ((mp_limb_t) qh << (GMP_LIMB_BITS / 2)) + ql;
733+ if (r >= u1)
734+ {
735+ m++;
736+ r -= u1;
737+ }
738+
739+ if (u0 > 0)
740+ {
741+ mp_limb_t th, tl;
742+ r = ~r;
743+ r += u0;
744+ if (r < u0)
745+ {
746+ m--;
747+ if (r >= u1)
748+ {
749+ m--;
750+ r -= u1;
751+ }
752+ r -= u1;
753+ }
754+ gmp_umul_ppmm (th, tl, u0, m);
755+ r += th;
756+ if (r < th)
757+ {
758+ m--;
759+ m -= ((r > u1) | ((r == u1) & (tl > u0)));
760+ }
761+ }
762+
763+ return m;
764+}
765+
766+struct gmp_div_inverse
767+{
768+ /* Normalization shift count. */
769+ unsigned shift;
770+ /* Normalized divisor (d0 unused for mpn_div_qr_1) */
771+ mp_limb_t d1, d0;
772+ /* Inverse, for 2/1 or 3/2. */
773+ mp_limb_t di;
774+};
775+
776+static void
777+mpn_div_qr_1_invert (struct gmp_div_inverse *inv, mp_limb_t d)
778+{
779+ unsigned shift;
780+
781+ assert (d > 0);
782+ gmp_clz (shift, d);
783+ inv->shift = shift;
784+ inv->d1 = d << shift;
785+ inv->di = mpn_invert_limb (inv->d1);
786+}
787+
788+static void
789+mpn_div_qr_2_invert (struct gmp_div_inverse *inv,
790+ mp_limb_t d1, mp_limb_t d0)
791+{
792+ unsigned shift;
793+
794+ assert (d1 > 0);
795+ gmp_clz (shift, d1);
796+ inv->shift = shift;
797+ if (shift > 0)
798+ {
799+ d1 = (d1 << shift) | (d0 >> (GMP_LIMB_BITS - shift));
800+ d0 <<= shift;
801+ }
802+ inv->d1 = d1;
803+ inv->d0 = d0;
804+ inv->di = mpn_invert_3by2 (d1, d0);
805+}
806+
807+static void
808+mpn_div_qr_invert (struct gmp_div_inverse *inv,
809+ mp_srcptr dp, mp_size_t dn)
810+{
811+ assert (dn > 0);
812+
813+ if (dn == 1)
814+ mpn_div_qr_1_invert (inv, dp[0]);
815+ else if (dn == 2)
816+ mpn_div_qr_2_invert (inv, dp[1], dp[0]);
817+ else
818+ {
819+ unsigned shift;
820+ mp_limb_t d1, d0;
821+
822+ d1 = dp[dn-1];
823+ d0 = dp[dn-2];
824+ assert (d1 > 0);
825+ gmp_clz (shift, d1);
826+ inv->shift = shift;
827+ if (shift > 0)
828+ {
829+ d1 = (d1 << shift) | (d0 >> (GMP_LIMB_BITS - shift));
830+ d0 = (d0 << shift) | (dp[dn-3] >> (GMP_LIMB_BITS - shift));
831+ }
832+ inv->d1 = d1;
833+ inv->d0 = d0;
834+ inv->di = mpn_invert_3by2 (d1, d0);
835+ }
836+}
837+
838+/* Not matching current public gmp interface, rather corresponding to
839+ the sbpi1_div_* functions. */
840+static mp_limb_t
841+mpn_div_qr_1_preinv (mp_ptr qp, mp_srcptr np, mp_size_t nn,
842+ const struct gmp_div_inverse *inv)
843+{
844+ mp_limb_t d, di;
845+ mp_limb_t r;
846+ mp_ptr tp = NULL;
847+
848+ if (inv->shift > 0)
849+ {
850+ tp = gmp_xalloc_limbs (nn);
851+ r = mpn_lshift (tp, np, nn, inv->shift);
852+ np = tp;
853+ }
854+ else
855+ r = 0;
856+
857+ d = inv->d1;
858+ di = inv->di;
859+ while (nn-- > 0)
860+ {
861+ mp_limb_t q;
862+
863+ gmp_udiv_qrnnd_preinv (q, r, r, np[nn], d, di);
864+ if (qp)
865+ qp[nn] = q;
866+ }
867+ if (inv->shift > 0)
868+ gmp_free (tp);
869+
870+ return r >> inv->shift;
871+}
872+
873+static mp_limb_t
874+mpn_div_qr_1 (mp_ptr qp, mp_srcptr np, mp_size_t nn, mp_limb_t d)
875+{
876+ assert (d > 0);
877+
878+ /* Special case for powers of two. */
879+ if ((d & (d-1)) == 0)
880+ {
881+ mp_limb_t r = np[0] & (d-1);
882+ if (qp)
883+ {
884+ if (d <= 1)
885+ mpn_copyi (qp, np, nn);
886+ else
887+ {
888+ unsigned shift;
889+ gmp_ctz (shift, d);
890+ mpn_rshift (qp, np, nn, shift);
891+ }
892+ }
893+ return r;
894+ }
895+ else
896+ {
897+ struct gmp_div_inverse inv;
898+ mpn_div_qr_1_invert (&inv, d);
899+ return mpn_div_qr_1_preinv (qp, np, nn, &inv);
900+ }
901+}
902+
903+static void
904+mpn_div_qr_2_preinv (mp_ptr qp, mp_ptr rp, mp_srcptr np, mp_size_t nn,
905+ const struct gmp_div_inverse *inv)
906+{
907+ unsigned shift;
908+ mp_size_t i;
909+ mp_limb_t d1, d0, di, r1, r0;
910+ mp_ptr tp;
911+
912+ assert (nn >= 2);
913+ shift = inv->shift;
914+ d1 = inv->d1;
915+ d0 = inv->d0;
916+ di = inv->di;
917+
918+ if (shift > 0)
919+ {
920+ tp = gmp_xalloc_limbs (nn);
921+ r1 = mpn_lshift (tp, np, nn, shift);
922+ np = tp;
923+ }
924+ else
925+ r1 = 0;
926+
927+ r0 = np[nn - 1];
928+
929+ i = nn - 2;
930+ do
931+ {
932+ mp_limb_t n0, q;
933+ n0 = np[i];
934+ gmp_udiv_qr_3by2 (q, r1, r0, r1, r0, n0, d1, d0, di);
935+
936+ if (qp)
937+ qp[i] = q;
938+ }
939+ while (--i >= 0);
940+
941+ if (shift > 0)
942+ {
943+ assert ((r0 << (GMP_LIMB_BITS - shift)) == 0);
944+ r0 = (r0 >> shift) | (r1 << (GMP_LIMB_BITS - shift));
945+ r1 >>= shift;
946+
947+ gmp_free (tp);
948+ }
949+
950+ rp[1] = r1;
951+ rp[0] = r0;
952+}
953+
954+#if 0
955+static void
956+mpn_div_qr_2 (mp_ptr qp, mp_ptr rp, mp_srcptr np, mp_size_t nn,
957+ mp_limb_t d1, mp_limb_t d0)
958+{
959+ struct gmp_div_inverse inv;
960+ assert (nn >= 2);
961+
962+ mpn_div_qr_2_invert (&inv, d1, d0);
963+ mpn_div_qr_2_preinv (qp, rp, np, nn, &inv);
964+}
965+#endif
966+
967+static void
968+mpn_div_qr_pi1 (mp_ptr qp,
969+ mp_ptr np, mp_size_t nn, mp_limb_t n1,
970+ mp_srcptr dp, mp_size_t dn,
971+ mp_limb_t dinv)
972+{
973+ mp_size_t i;
974+
975+ mp_limb_t d1, d0;
976+ mp_limb_t cy, cy1;
977+ mp_limb_t q;
978+
979+ assert (dn > 2);
980+ assert (nn >= dn);
981+
982+ d1 = dp[dn - 1];
983+ d0 = dp[dn - 2];
984+
985+ assert ((d1 & GMP_LIMB_HIGHBIT) != 0);
986+ /* Iteration variable is the index of the q limb.
987+ *
988+ * We divide <n1, np[dn-1+i], np[dn-2+i], np[dn-3+i],..., np[i]>
989+ * by <d1, d0, dp[dn-3], ..., dp[0] >
990+ */
991+
992+ i = nn - dn;
993+ do
994+ {
995+ mp_limb_t n0 = np[dn-1+i];
996+
997+ if (n1 == d1 && n0 == d0)
998+ {
999+ q = GMP_LIMB_MAX;
1000+ mpn_submul_1 (np+i, dp, dn, q);
1001+ n1 = np[dn-1+i]; /* update n1, last loop's value will now be invalid */
1002+ }
1003+ else
1004+ {
1005+ gmp_udiv_qr_3by2 (q, n1, n0, n1, n0, np[dn-2+i], d1, d0, dinv);
1006+
1007+ cy = mpn_submul_1 (np + i, dp, dn-2, q);
1008+
1009+ cy1 = n0 < cy;
1010+ n0 = n0 - cy;
1011+ cy = n1 < cy1;
1012+ n1 = n1 - cy1;
1013+ np[dn-2+i] = n0;
1014+
1015+ if (cy != 0)
1016+ {
1017+ n1 += d1 + mpn_add_n (np + i, np + i, dp, dn - 1);
1018+ q--;
1019+ }
1020+ }
1021+
1022+ if (qp)
1023+ qp[i] = q;
1024+ }
1025+ while (--i >= 0);
1026+
1027+ np[dn - 1] = n1;
1028+}
1029+
1030+static void
1031+mpn_div_qr_preinv (mp_ptr qp, mp_ptr np, mp_size_t nn,
1032+ mp_srcptr dp, mp_size_t dn,
1033+ const struct gmp_div_inverse *inv)
1034+{
1035+ assert (dn > 0);
1036+ assert (nn >= dn);
1037+
1038+ if (dn == 1)
1039+ np[0] = mpn_div_qr_1_preinv (qp, np, nn, inv);
1040+ else if (dn == 2)
1041+ mpn_div_qr_2_preinv (qp, np, np, nn, inv);
1042+ else
1043+ {
1044+ mp_limb_t nh;
1045+ unsigned shift;
1046+
1047+ assert (inv->d1 == dp[dn-1]);
1048+ assert (inv->d0 == dp[dn-2]);
1049+ assert ((inv->d1 & GMP_LIMB_HIGHBIT) != 0);
1050+
1051+ shift = inv->shift;
1052+ if (shift > 0)
1053+ nh = mpn_lshift (np, np, nn, shift);
1054+ else
1055+ nh = 0;
1056+
1057+ mpn_div_qr_pi1 (qp, np, nn, nh, dp, dn, inv->di);
1058+
1059+ if (shift > 0)
1060+ gmp_assert_nocarry (mpn_rshift (np, np, dn, shift));
1061+ }
1062+}
1063+
1064+static void
1065+mpn_div_qr (mp_ptr qp, mp_ptr np, mp_size_t nn, mp_srcptr dp, mp_size_t dn)
1066+{
1067+ struct gmp_div_inverse inv;
1068+ mp_ptr tp = NULL;
1069+
1070+ assert (dn > 0);
1071+ assert (nn >= dn);
1072+
1073+ mpn_div_qr_invert (&inv, dp, dn);
1074+ if (dn > 2 && inv.shift > 0)
1075+ {
1076+ tp = gmp_xalloc_limbs (dn);
1077+ gmp_assert_nocarry (mpn_lshift (tp, dp, dn, inv.shift));
1078+ dp = tp;
1079+ }
1080+ mpn_div_qr_preinv (qp, np, nn, dp, dn, &inv);
1081+ if (tp)
1082+ gmp_free (tp);
1083+}
1084+
1085+
1086+/* MPN base conversion. */
1087+static unsigned
1088+mpn_base_power_of_two_p (unsigned b)
1089+{
1090+ switch (b)
1091+ {
1092+ case 2: return 1;
1093+ case 4: return 2;
1094+ case 8: return 3;
1095+ case 16: return 4;
1096+ case 32: return 5;
1097+ case 64: return 6;
1098+ case 128: return 7;
1099+ case 256: return 8;
1100+ default: return 0;
1101+ }
1102+}
1103+
1104+struct mpn_base_info
1105+{
1106+ /* bb is the largest power of the base which fits in one limb, and
1107+ exp is the corresponding exponent. */
1108+ unsigned exp;
1109+ mp_limb_t bb;
1110+};
1111+
1112+static void
1113+mpn_get_base_info (struct mpn_base_info *info, mp_limb_t b)
1114+{
1115+ mp_limb_t m;
1116+ mp_limb_t p;
1117+ unsigned exp;
1118+
1119+ m = GMP_LIMB_MAX / b;
1120+ for (exp = 1, p = b; p <= m; exp++)
1121+ p *= b;
1122+
1123+ info->exp = exp;
1124+ info->bb = p;
1125+}
1126+
1127+static mp_bitcnt_t
1128+mpn_limb_size_in_base_2 (mp_limb_t u)
1129+{
1130+ unsigned shift;
1131+
1132+ assert (u > 0);
1133+ gmp_clz (shift, u);
1134+ return GMP_LIMB_BITS - shift;
1135+}
1136+
1137+static size_t
1138+mpn_get_str_bits (unsigned char *sp, unsigned bits, mp_srcptr up, mp_size_t un)
1139+{
1140+ unsigned char mask;
1141+ size_t sn, j;
1142+ mp_size_t i;
1143+ int shift;
1144+
1145+ sn = ((un - 1) * GMP_LIMB_BITS + mpn_limb_size_in_base_2 (up[un-1])
1146+ + bits - 1) / bits;
1147+
1148+ mask = (1U << bits) - 1;
1149+
1150+ for (i = 0, j = sn, shift = 0; j-- > 0;)
1151+ {
1152+ unsigned char digit = up[i] >> shift;
1153+
1154+ shift += bits;
1155+
1156+ if (shift >= GMP_LIMB_BITS && ++i < un)
1157+ {
1158+ shift -= GMP_LIMB_BITS;
1159+ digit |= up[i] << (bits - shift);
1160+ }
1161+ sp[j] = digit & mask;
1162+ }
1163+ return sn;
1164+}
1165+
1166+/* We generate digits from the least significant end, and reverse at
1167+ the end. */
1168+static size_t
1169+mpn_limb_get_str (unsigned char *sp, mp_limb_t w,
1170+ const struct gmp_div_inverse *binv)
1171+{
1172+ mp_size_t i;
1173+ for (i = 0; w > 0; i++)
1174+ {
1175+ mp_limb_t h, l, r;
1176+
1177+ h = w >> (GMP_LIMB_BITS - binv->shift);
1178+ l = w << binv->shift;
1179+
1180+ gmp_udiv_qrnnd_preinv (w, r, h, l, binv->d1, binv->di);
1181+ assert ( (r << (GMP_LIMB_BITS - binv->shift)) == 0);
1182+ r >>= binv->shift;
1183+
1184+ sp[i] = r;
1185+ }
1186+ return i;
1187+}
1188+
1189+static size_t
1190+mpn_get_str_other (unsigned char *sp,
1191+ int base, const struct mpn_base_info *info,
1192+ mp_ptr up, mp_size_t un)
1193+{
1194+ struct gmp_div_inverse binv;
1195+ size_t sn;
1196+ size_t i;
1197+
1198+ mpn_div_qr_1_invert (&binv, base);
1199+
1200+ sn = 0;
1201+
1202+ if (un > 1)
1203+ {
1204+ struct gmp_div_inverse bbinv;
1205+ mpn_div_qr_1_invert (&bbinv, info->bb);
1206+
1207+ do
1208+ {
1209+ mp_limb_t w;
1210+ size_t done;
1211+ w = mpn_div_qr_1_preinv (up, up, un, &bbinv);
1212+ un -= (up[un-1] == 0);
1213+ done = mpn_limb_get_str (sp + sn, w, &binv);
1214+
1215+ for (sn += done; done < info->exp; done++)
1216+ sp[sn++] = 0;
1217+ }
1218+ while (un > 1);
1219+ }
1220+ sn += mpn_limb_get_str (sp + sn, up[0], &binv);
1221+
1222+ /* Reverse order */
1223+ for (i = 0; 2*i + 1 < sn; i++)
1224+ {
1225+ unsigned char t = sp[i];
1226+ sp[i] = sp[sn - i - 1];
1227+ sp[sn - i - 1] = t;
1228+ }
1229+
1230+ return sn;
1231+}
1232+
1233+size_t
1234+mpn_get_str (unsigned char *sp, int base, mp_ptr up, mp_size_t un)
1235+{
1236+ unsigned bits;
1237+
1238+ assert (un > 0);
1239+ assert (up[un-1] > 0);
1240+
1241+ bits = mpn_base_power_of_two_p (base);
1242+ if (bits)
1243+ return mpn_get_str_bits (sp, bits, up, un);
1244+ else
1245+ {
1246+ struct mpn_base_info info;
1247+
1248+ mpn_get_base_info (&info, base);
1249+ return mpn_get_str_other (sp, base, &info, up, un);
1250+ }
1251+}
1252+
1253+static mp_size_t
1254+mpn_set_str_bits (mp_ptr rp, const unsigned char *sp, size_t sn,
1255+ unsigned bits)
1256+{
1257+ mp_size_t rn;
1258+ size_t j;
1259+ unsigned shift;
1260+
1261+ for (j = sn, rn = 0, shift = 0; j-- > 0; )
1262+ {
1263+ if (shift == 0)
1264+ {
1265+ rp[rn++] = sp[j];
1266+ shift += bits;
1267+ }
1268+ else
1269+ {
1270+ rp[rn-1] |= (mp_limb_t) sp[j] << shift;
1271+ shift += bits;
1272+ if (shift >= GMP_LIMB_BITS)
1273+ {
1274+ shift -= GMP_LIMB_BITS;
1275+ if (shift > 0)
1276+ rp[rn++] = (mp_limb_t) sp[j] >> (bits - shift);
1277+ }
1278+ }
1279+ }
1280+ rn = mpn_normalized_size (rp, rn);
1281+ return rn;
1282+}
1283+
1284+static mp_size_t
1285+mpn_set_str_other (mp_ptr rp, const unsigned char *sp, size_t sn,
1286+ mp_limb_t b, const struct mpn_base_info *info)
1287+{
1288+ mp_size_t rn;
1289+ mp_limb_t w;
1290+ unsigned k;
1291+ size_t j;
1292+
1293+ k = 1 + (sn - 1) % info->exp;
1294+
1295+ j = 0;
1296+ w = sp[j++];
1297+ for (; --k > 0; )
1298+ w = w * b + sp[j++];
1299+
1300+ rp[0] = w;
1301+
1302+ for (rn = (w > 0); j < sn;)
1303+ {
1304+ mp_limb_t cy;
1305+
1306+ w = sp[j++];
1307+ for (k = 1; k < info->exp; k++)
1308+ w = w * b + sp[j++];
1309+
1310+ cy = mpn_mul_1 (rp, rp, rn, info->bb);
1311+ cy += mpn_add_1 (rp, rp, rn, w);
1312+ if (cy > 0)
1313+ rp[rn++] = cy;
1314+ }
1315+ assert (j == sn);
1316+
1317+ return rn;
1318+}
1319+
1320+mp_size_t
1321+mpn_set_str (mp_ptr rp, const unsigned char *sp, size_t sn, int base)
1322+{
1323+ unsigned bits;
1324+
1325+ if (sn == 0)
1326+ return 0;
1327+
1328+ bits = mpn_base_power_of_two_p (base);
1329+ if (bits)
1330+ return mpn_set_str_bits (rp, sp, sn, bits);
1331+ else
1332+ {
1333+ struct mpn_base_info info;
1334+
1335+ mpn_get_base_info (&info, base);
1336+ return mpn_set_str_other (rp, sp, sn, base, &info);
1337+ }
1338+}
1339+
1340+
1341+/* MPZ interface */
1342+void
1343+mpz_init (mpz_t r)
1344+{
1345+ r->_mp_alloc = 1;
1346+ r->_mp_size = 0;
1347+ r->_mp_d = gmp_xalloc_limbs (1);
1348+}
1349+
1350+/* The utility of this function is a bit limited, since many functions
1351+ assigns the result variable using mpz_swap. */
1352+void
1353+mpz_init2 (mpz_t r, mp_bitcnt_t bits)
1354+{
1355+ mp_size_t rn;
1356+
1357+ bits -= (bits != 0); /* Round down, except if 0 */
1358+ rn = 1 + bits / GMP_LIMB_BITS;
1359+
1360+ r->_mp_alloc = rn;
1361+ r->_mp_size = 0;
1362+ r->_mp_d = gmp_xalloc_limbs (rn);
1363+}
1364+
1365+void
1366+mpz_clear (mpz_t r)
1367+{
1368+ gmp_free (r->_mp_d);
1369+}
1370+
1371+static void *
1372+mpz_realloc (mpz_t r, mp_size_t size)
1373+{
1374+ size = GMP_MAX (size, 1);
1375+
1376+ r->_mp_d = gmp_xrealloc_limbs (r->_mp_d, size);
1377+ r->_mp_alloc = size;
1378+
1379+ if (GMP_ABS (r->_mp_size) > size)
1380+ r->_mp_size = 0;
1381+
1382+ return r->_mp_d;
1383+}
1384+
1385+/* Realloc for an mpz_t WHAT if it has less than NEEDED limbs. */
1386+#define MPZ_REALLOC(z,n) ((n) > (z)->_mp_alloc \
1387+ ? mpz_realloc(z,n) \
1388+ : (z)->_mp_d)
1389+
1390+/* MPZ assignment and basic conversions. */
1391+void
1392+mpz_set_si (mpz_t r, signed long int x)
1393+{
1394+ if (x >= 0)
1395+ mpz_set_ui (r, x);
1396+ else /* (x < 0) */
1397+ {
1398+ r->_mp_size = -1;
1399+ r->_mp_d[0] = GMP_NEG_CAST (unsigned long int, x);
1400+ }
1401+}
1402+
1403+void
1404+mpz_set_ui (mpz_t r, unsigned long int x)
1405+{
1406+ if (x > 0)
1407+ {
1408+ r->_mp_size = 1;
1409+ r->_mp_d[0] = x;
1410+ }
1411+ else
1412+ r->_mp_size = 0;
1413+}
1414+
1415+void
1416+mpz_set (mpz_t r, const mpz_t x)
1417+{
1418+ /* Allow the NOP r == x */
1419+ if (r != x)
1420+ {
1421+ mp_size_t n;
1422+ mp_ptr rp;
1423+
1424+ n = GMP_ABS (x->_mp_size);
1425+ rp = MPZ_REALLOC (r, n);
1426+
1427+ mpn_copyi (rp, x->_mp_d, n);
1428+ r->_mp_size = x->_mp_size;
1429+ }
1430+}
1431+
1432+void
1433+mpz_init_set_si (mpz_t r, signed long int x)
1434+{
1435+ mpz_init (r);
1436+ mpz_set_si (r, x);
1437+}
1438+
1439+void
1440+mpz_init_set_ui (mpz_t r, unsigned long int x)
1441+{
1442+ mpz_init (r);
1443+ mpz_set_ui (r, x);
1444+}
1445+
1446+void
1447+mpz_init_set (mpz_t r, const mpz_t x)
1448+{
1449+ mpz_init (r);
1450+ mpz_set (r, x);
1451+}
1452+
1453+int
1454+mpz_fits_slong_p (const mpz_t u)
1455+{
1456+ mp_size_t us = u->_mp_size;
1457+
1458+ if (us == 0)
1459+ return 1;
1460+ else if (us == 1)
1461+ return u->_mp_d[0] < GMP_LIMB_HIGHBIT;
1462+ else if (us == -1)
1463+ return u->_mp_d[0] <= GMP_LIMB_HIGHBIT;
1464+ else
1465+ return 0;
1466+}
1467+
1468+int
1469+mpz_fits_ulong_p (const mpz_t u)
1470+{
1471+ mp_size_t us = u->_mp_size;
1472+
1473+ return (us == (us > 0));
1474+}
1475+
1476+long int
1477+mpz_get_si (const mpz_t u)
1478+{
1479+ mp_size_t us = u->_mp_size;
1480+
1481+ if (us > 0)
1482+ return (long) (u->_mp_d[0] & ~GMP_LIMB_HIGHBIT);
1483+ else if (us < 0)
1484+ return (long) (- u->_mp_d[0] | GMP_LIMB_HIGHBIT);
1485+ else
1486+ return 0;
1487+}
1488+
1489+unsigned long int
1490+mpz_get_ui (const mpz_t u)
1491+{
1492+ return u->_mp_size == 0 ? 0 : u->_mp_d[0];
1493+}
1494+
1495+size_t
1496+mpz_size (const mpz_t u)
1497+{
1498+ return GMP_ABS (u->_mp_size);
1499+}
1500+
1501+mp_limb_t
1502+mpz_getlimbn (const mpz_t u, mp_size_t n)
1503+{
1504+ if (n >= 0 && n < GMP_ABS (u->_mp_size))
1505+ return u->_mp_d[n];
1506+ else
1507+ return 0;
1508+}
1509+
1510+
1511+/* Conversions and comparison to double. */
1512+void
1513+mpz_set_d (mpz_t r, double x)
1514+{
1515+ int sign;
1516+ mp_ptr rp;
1517+ mp_size_t rn, i;
1518+ double B;
1519+ double Bi;
1520+ mp_limb_t f;
1521+
1522+ /* x != x is true when x is a NaN, and x == x * 0.5 is true when x is
1523+ zero or infinity. */
1524+ if (x != x || x == x * 0.5)
1525+ {
1526+ r->_mp_size = 0;
1527+ return;
1528+ }
1529+
1530+ sign = x < 0.0 ;
1531+ if (sign)
1532+ x = - x;
1533+
1534+ if (x < 1.0)
1535+ {
1536+ r->_mp_size = 0;
1537+ return;
1538+ }
1539+ B = 2.0 * (double) GMP_LIMB_HIGHBIT;
1540+ Bi = 1.0 / B;
1541+ for (rn = 1; x >= B; rn++)
1542+ x *= Bi;
1543+
1544+ rp = MPZ_REALLOC (r, rn);
1545+
1546+ f = (mp_limb_t) x;
1547+ x -= f;
1548+ assert (x < 1.0);
1549+ i = rn-1;
1550+ rp[i] = f;
1551+ while (--i >= 0)
1552+ {
1553+ x = B * x;
1554+ f = (mp_limb_t) x;
1555+ x -= f;
1556+ assert (x < 1.0);
1557+ rp[i] = f;
1558+ }
1559+
1560+ r->_mp_size = sign ? - rn : rn;
1561+}
1562+
1563+void
1564+mpz_init_set_d (mpz_t r, double x)
1565+{
1566+ mpz_init (r);
1567+ mpz_set_d (r, x);
1568+}
1569+
1570+double
1571+mpz_get_d (const mpz_t u)
1572+{
1573+ mp_size_t un;
1574+ double x;
1575+ double B = 2.0 * (double) GMP_LIMB_HIGHBIT;
1576+
1577+ un = GMP_ABS (u->_mp_size);
1578+
1579+ if (un == 0)
1580+ return 0.0;
1581+
1582+ x = u->_mp_d[--un];
1583+ while (un > 0)
1584+ x = B*x + u->_mp_d[--un];
1585+
1586+ if (u->_mp_size < 0)
1587+ x = -x;
1588+
1589+ return x;
1590+}
1591+
1592+int
1593+mpz_cmpabs_d (const mpz_t x, double d)
1594+{
1595+ mp_size_t xn;
1596+ double B, Bi;
1597+ mp_size_t i;
1598+
1599+ xn = x->_mp_size;
1600+ d = GMP_ABS (d);
1601+
1602+ if (xn != 0)
1603+ {
1604+ xn = GMP_ABS (xn);
1605+
1606+ B = 2.0 * (double) GMP_LIMB_HIGHBIT;
1607+ Bi = 1.0 / B;
1608+
1609+ /* Scale d so it can be compared with the top limb. */
1610+ for (i = 1; i < xn; i++)
1611+ d *= Bi;
1612+
1613+ if (d >= B)
1614+ return -1;
1615+
1616+ /* Compare floor(d) to top limb, subtract and cancel when equal. */
1617+ for (i = xn; i-- > 0;)
1618+ {
1619+ mp_limb_t f, xl;
1620+
1621+ f = (mp_limb_t) d;
1622+ xl = x->_mp_d[i];
1623+ if (xl > f)
1624+ return 1;
1625+ else if (xl < f)
1626+ return -1;
1627+ d = B * (d - f);
1628+ }
1629+ }
1630+ return - (d > 0.0);
1631+}
1632+
1633+int
1634+mpz_cmp_d (const mpz_t x, double d)
1635+{
1636+ if (x->_mp_size < 0)
1637+ {
1638+ if (d >= 0.0)
1639+ return -1;
1640+ else
1641+ return -mpz_cmpabs_d (x, d);
1642+ }
1643+ else
1644+ {
1645+ if (d < 0.0)
1646+ return 1;
1647+ else
1648+ return mpz_cmpabs_d (x, d);
1649+ }
1650+}
1651+
1652+
1653+/* MPZ comparisons and the like. */
1654+int
1655+mpz_sgn (const mpz_t u)
1656+{
1657+ mp_size_t usize = u->_mp_size;
1658+
1659+ return (usize > 0) - (usize < 0);
1660+}
1661+
1662+int
1663+mpz_cmp_si (const mpz_t u, long v)
1664+{
1665+ mp_size_t usize = u->_mp_size;
1666+
1667+ if (usize < -1)
1668+ return -1;
1669+ else if (v >= 0)
1670+ return mpz_cmp_ui (u, v);
1671+ else if (usize >= 0)
1672+ return 1;
1673+ else /* usize == -1 */
1674+ {
1675+ mp_limb_t ul = u->_mp_d[0];
1676+ if ((mp_limb_t)GMP_NEG_CAST (unsigned long int, v) < ul)
1677+ return -1;
1678+ else
1679+ return (mp_limb_t)GMP_NEG_CAST (unsigned long int, v) > ul;
1680+ }
1681+}
1682+
1683+int
1684+mpz_cmp_ui (const mpz_t u, unsigned long v)
1685+{
1686+ mp_size_t usize = u->_mp_size;
1687+
1688+ if (usize > 1)
1689+ return 1;
1690+ else if (usize < 0)
1691+ return -1;
1692+ else
1693+ {
1694+ mp_limb_t ul = (usize > 0) ? u->_mp_d[0] : 0;
1695+ return (ul > v) - (ul < v);
1696+ }
1697+}
1698+
1699+int
1700+mpz_cmp (const mpz_t a, const mpz_t b)
1701+{
1702+ mp_size_t asize = a->_mp_size;
1703+ mp_size_t bsize = b->_mp_size;
1704+
1705+ if (asize != bsize)
1706+ return (asize < bsize) ? -1 : 1;
1707+ else if (asize >= 0)
1708+ return mpn_cmp (a->_mp_d, b->_mp_d, asize);
1709+ else
1710+ return mpn_cmp (b->_mp_d, a->_mp_d, -asize);
1711+}
1712+
1713+int
1714+mpz_cmpabs_ui (const mpz_t u, unsigned long v)
1715+{
1716+ mp_size_t un = GMP_ABS (u->_mp_size);
1717+ mp_limb_t ul;
1718+
1719+ if (un > 1)
1720+ return 1;
1721+
1722+ ul = (un == 1) ? u->_mp_d[0] : 0;
1723+
1724+ return (ul > v) - (ul < v);
1725+}
1726+
1727+int
1728+mpz_cmpabs (const mpz_t u, const mpz_t v)
1729+{
1730+ return mpn_cmp4 (u->_mp_d, GMP_ABS (u->_mp_size),
1731+ v->_mp_d, GMP_ABS (v->_mp_size));
1732+}
1733+
1734+void
1735+mpz_abs (mpz_t r, const mpz_t u)
1736+{
1737+ if (r != u)
1738+ mpz_set (r, u);
1739+
1740+ r->_mp_size = GMP_ABS (r->_mp_size);
1741+}
1742+
1743+void
1744+mpz_neg (mpz_t r, const mpz_t u)
1745+{
1746+ if (r != u)
1747+ mpz_set (r, u);
1748+
1749+ r->_mp_size = -r->_mp_size;
1750+}
1751+
1752+void
1753+mpz_swap (mpz_t u, mpz_t v)
1754+{
1755+ MP_SIZE_T_SWAP (u->_mp_size, v->_mp_size);
1756+ MP_SIZE_T_SWAP (u->_mp_alloc, v->_mp_alloc);
1757+ MP_PTR_SWAP (u->_mp_d, v->_mp_d);
1758+}
1759+
1760+
1761+/* MPZ addition and subtraction */
1762+
1763+/* Adds to the absolute value. Returns new size, but doesn't store it. */
1764+static mp_size_t
1765+mpz_abs_add_ui (mpz_t r, const mpz_t a, unsigned long b)
1766+{
1767+ mp_size_t an;
1768+ mp_ptr rp;
1769+ mp_limb_t cy;
1770+
1771+ an = GMP_ABS (a->_mp_size);
1772+ if (an == 0)
1773+ {
1774+ r->_mp_d[0] = b;
1775+ return b > 0;
1776+ }
1777+
1778+ rp = MPZ_REALLOC (r, an + 1);
1779+
1780+ cy = mpn_add_1 (rp, a->_mp_d, an, b);
1781+ rp[an] = cy;
1782+ an += cy;
1783+
1784+ return an;
1785+}
1786+
1787+/* Subtract from the absolute value. Returns new size, (or -1 on underflow),
1788+ but doesn't store it. */
1789+static mp_size_t
1790+mpz_abs_sub_ui (mpz_t r, const mpz_t a, unsigned long b)
1791+{
1792+ mp_size_t an = GMP_ABS (a->_mp_size);
1793+ mp_ptr rp = MPZ_REALLOC (r, an);
1794+
1795+ if (an == 0)
1796+ {
1797+ rp[0] = b;
1798+ return -(b > 0);
1799+ }
1800+ else if (an == 1 && a->_mp_d[0] < b)
1801+ {
1802+ rp[0] = b - a->_mp_d[0];
1803+ return -1;
1804+ }
1805+ else
1806+ {
1807+ gmp_assert_nocarry (mpn_sub_1 (rp, a->_mp_d, an, b));
1808+ return mpn_normalized_size (rp, an);
1809+ }
1810+}
1811+
1812+void
1813+mpz_add_ui (mpz_t r, const mpz_t a, unsigned long b)
1814+{
1815+ if (a->_mp_size >= 0)
1816+ r->_mp_size = mpz_abs_add_ui (r, a, b);
1817+ else
1818+ r->_mp_size = -mpz_abs_sub_ui (r, a, b);
1819+}
1820+
1821+void
1822+mpz_sub_ui (mpz_t r, const mpz_t a, unsigned long b)
1823+{
1824+ if (a->_mp_size < 0)
1825+ r->_mp_size = -mpz_abs_add_ui (r, a, b);
1826+ else
1827+ r->_mp_size = mpz_abs_sub_ui (r, a, b);
1828+}
1829+
1830+void
1831+mpz_ui_sub (mpz_t r, unsigned long a, const mpz_t b)
1832+{
1833+ if (b->_mp_size < 0)
1834+ r->_mp_size = mpz_abs_add_ui (r, b, a);
1835+ else
1836+ r->_mp_size = -mpz_abs_sub_ui (r, b, a);
1837+}
1838+
1839+static mp_size_t
1840+mpz_abs_add (mpz_t r, const mpz_t a, const mpz_t b)
1841+{
1842+ mp_size_t an = GMP_ABS (a->_mp_size);
1843+ mp_size_t bn = GMP_ABS (b->_mp_size);
1844+ mp_ptr rp;
1845+ mp_limb_t cy;
1846+
1847+ if (an < bn)
1848+ {
1849+ MPZ_SRCPTR_SWAP (a, b);
1850+ MP_SIZE_T_SWAP (an, bn);
1851+ }
1852+
1853+ rp = MPZ_REALLOC (r, an + 1);
1854+ cy = mpn_add (rp, a->_mp_d, an, b->_mp_d, bn);
1855+
1856+ rp[an] = cy;
1857+
1858+ return an + cy;
1859+}
1860+
1861+static mp_size_t
1862+mpz_abs_sub (mpz_t r, const mpz_t a, const mpz_t b)
1863+{
1864+ mp_size_t an = GMP_ABS (a->_mp_size);
1865+ mp_size_t bn = GMP_ABS (b->_mp_size);
1866+ int cmp;
1867+ mp_ptr rp;
1868+
1869+ cmp = mpn_cmp4 (a->_mp_d, an, b->_mp_d, bn);
1870+ if (cmp > 0)
1871+ {
1872+ rp = MPZ_REALLOC (r, an);
1873+ gmp_assert_nocarry (mpn_sub (rp, a->_mp_d, an, b->_mp_d, bn));
1874+ return mpn_normalized_size (rp, an);
1875+ }
1876+ else if (cmp < 0)
1877+ {
1878+ rp = MPZ_REALLOC (r, bn);
1879+ gmp_assert_nocarry (mpn_sub (rp, b->_mp_d, bn, a->_mp_d, an));
1880+ return -mpn_normalized_size (rp, bn);
1881+ }
1882+ else
1883+ return 0;
1884+}
1885+
1886+void
1887+mpz_add (mpz_t r, const mpz_t a, const mpz_t b)
1888+{
1889+ mp_size_t rn;
1890+
1891+ if ( (a->_mp_size ^ b->_mp_size) >= 0)
1892+ rn = mpz_abs_add (r, a, b);
1893+ else
1894+ rn = mpz_abs_sub (r, a, b);
1895+
1896+ r->_mp_size = a->_mp_size >= 0 ? rn : - rn;
1897+}
1898+
1899+void
1900+mpz_sub (mpz_t r, const mpz_t a, const mpz_t b)
1901+{
1902+ mp_size_t rn;
1903+
1904+ if ( (a->_mp_size ^ b->_mp_size) >= 0)
1905+ rn = mpz_abs_sub (r, a, b);
1906+ else
1907+ rn = mpz_abs_add (r, a, b);
1908+
1909+ r->_mp_size = a->_mp_size >= 0 ? rn : - rn;
1910+}
1911+
1912+
1913+/* MPZ multiplication */
1914+void
1915+mpz_mul_si (mpz_t r, const mpz_t u, long int v)
1916+{
1917+ if (v < 0)
1918+ {
1919+ mpz_mul_ui (r, u, GMP_NEG_CAST (unsigned long int, v));
1920+ mpz_neg (r, r);
1921+ }
1922+ else
1923+ mpz_mul_ui (r, u, (unsigned long int) v);
1924+}
1925+
1926+void
1927+mpz_mul_ui (mpz_t r, const mpz_t u, unsigned long int v)
1928+{
1929+ mp_size_t un, us;
1930+ mp_ptr tp;
1931+ mp_limb_t cy;
1932+
1933+ us = u->_mp_size;
1934+
1935+ if (us == 0 || v == 0)
1936+ {
1937+ r->_mp_size = 0;
1938+ return;
1939+ }
1940+
1941+ un = GMP_ABS (us);
1942+
1943+ tp = MPZ_REALLOC (r, un + 1);
1944+ cy = mpn_mul_1 (tp, u->_mp_d, un, v);
1945+ tp[un] = cy;
1946+
1947+ un += (cy > 0);
1948+ r->_mp_size = (us < 0) ? - un : un;
1949+}
1950+
1951+void
1952+mpz_mul (mpz_t r, const mpz_t u, const mpz_t v)
1953+{
1954+ int sign;
1955+ mp_size_t un, vn, rn;
1956+ mpz_t t;
1957+ mp_ptr tp;
1958+
1959+ un = u->_mp_size;
1960+ vn = v->_mp_size;
1961+
1962+ if (un == 0 || vn == 0)
1963+ {
1964+ r->_mp_size = 0;
1965+ return;
1966+ }
1967+
1968+ sign = (un ^ vn) < 0;
1969+
1970+ un = GMP_ABS (un);
1971+ vn = GMP_ABS (vn);
1972+
1973+ mpz_init2 (t, (un + vn) * GMP_LIMB_BITS);
1974+
1975+ tp = t->_mp_d;
1976+ if (un >= vn)
1977+ mpn_mul (tp, u->_mp_d, un, v->_mp_d, vn);
1978+ else
1979+ mpn_mul (tp, v->_mp_d, vn, u->_mp_d, un);
1980+
1981+ rn = un + vn;
1982+ rn -= tp[rn-1] == 0;
1983+
1984+ t->_mp_size = sign ? - rn : rn;
1985+ mpz_swap (r, t);
1986+ mpz_clear (t);
1987+}
1988+
1989+void
1990+mpz_mul_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t bits)
1991+{
1992+ mp_size_t un, rn;
1993+ mp_size_t limbs;
1994+ unsigned shift;
1995+ mp_ptr rp;
1996+
1997+ un = GMP_ABS (u->_mp_size);
1998+ if (un == 0)
1999+ {
2000+ r->_mp_size = 0;
2001+ return;
2002+ }
2003+
2004+ limbs = bits / GMP_LIMB_BITS;
2005+ shift = bits % GMP_LIMB_BITS;
2006+
2007+ rn = un + limbs + (shift > 0);
2008+ rp = MPZ_REALLOC (r, rn);
2009+ if (shift > 0)
2010+ {
2011+ mp_limb_t cy = mpn_lshift (rp + limbs, u->_mp_d, un, shift);
2012+ rp[rn-1] = cy;
2013+ rn -= (cy == 0);
2014+ }
2015+ else
2016+ mpn_copyd (rp + limbs, u->_mp_d, un);
2017+
2018+ while (limbs > 0)
2019+ rp[--limbs] = 0;
2020+
2021+ r->_mp_size = (u->_mp_size < 0) ? - rn : rn;
2022+}
2023+
2024+
2025+/* MPZ division */
2026+enum mpz_div_round_mode { GMP_DIV_FLOOR, GMP_DIV_CEIL, GMP_DIV_TRUNC };
2027+
2028+/* Allows q or r to be zero. Returns 1 iff remainder is non-zero. */
2029+static int
2030+mpz_div_qr (mpz_t q, mpz_t r,
2031+ const mpz_t n, const mpz_t d, enum mpz_div_round_mode mode)
2032+{
2033+ mp_size_t ns, ds, nn, dn, qs;
2034+ ns = n->_mp_size;
2035+ ds = d->_mp_size;
2036+
2037+ if (ds == 0)
2038+ gmp_die("mpz_div_qr: Divide by zero.");
2039+
2040+ if (ns == 0)
2041+ {
2042+ if (q)
2043+ q->_mp_size = 0;
2044+ if (r)
2045+ r->_mp_size = 0;
2046+ return 0;
2047+ }
2048+
2049+ nn = GMP_ABS (ns);
2050+ dn = GMP_ABS (ds);
2051+
2052+ qs = ds ^ ns;
2053+
2054+ if (nn < dn)
2055+ {
2056+ if (mode == GMP_DIV_CEIL && qs >= 0)
2057+ {
2058+ /* q = 1, r = n - d */
2059+ if (r)
2060+ mpz_sub (r, n, d);
2061+ if (q)
2062+ mpz_set_ui (q, 1);
2063+ }
2064+ else if (mode == GMP_DIV_FLOOR && qs < 0)
2065+ {
2066+ /* q = -1, r = n + d */
2067+ if (r)
2068+ mpz_add (r, n, d);
2069+ if (q)
2070+ mpz_set_si (q, -1);
2071+ }
2072+ else
2073+ {
2074+ /* q = 0, r = d */
2075+ if (r)
2076+ mpz_set (r, n);
2077+ if (q)
2078+ q->_mp_size = 0;
2079+ }
2080+ return 1;
2081+ }
2082+ else
2083+ {
2084+ mp_ptr np, qp;
2085+ mp_size_t qn, rn;
2086+ mpz_t tq, tr;
2087+
2088+ mpz_init (tr);
2089+ mpz_set (tr, n);
2090+ np = tr->_mp_d;
2091+
2092+ qn = nn - dn + 1;
2093+
2094+ if (q)
2095+ {
2096+ mpz_init2 (tq, qn * GMP_LIMB_BITS);
2097+ qp = tq->_mp_d;
2098+ }
2099+ else
2100+ qp = NULL;
2101+
2102+ mpn_div_qr (qp, np, nn, d->_mp_d, dn);
2103+
2104+ if (qp)
2105+ {
2106+ qn -= (qp[qn-1] == 0);
2107+
2108+ tq->_mp_size = qs < 0 ? -qn : qn;
2109+ }
2110+ rn = mpn_normalized_size (np, dn);
2111+ tr->_mp_size = ns < 0 ? - rn : rn;
2112+
2113+ if (mode == GMP_DIV_FLOOR && qs < 0 && rn != 0)
2114+ {
2115+ if (q)
2116+ mpz_sub_ui (tq, tq, 1);
2117+ if (r)
2118+ mpz_add (tr, tr, d);
2119+ }
2120+ else if (mode == GMP_DIV_CEIL && qs >= 0 && rn != 0)
2121+ {
2122+ if (q)
2123+ mpz_add_ui (tq, tq, 1);
2124+ if (r)
2125+ mpz_sub (tr, tr, d);
2126+ }
2127+
2128+ if (q)
2129+ {
2130+ mpz_swap (tq, q);
2131+ mpz_clear (tq);
2132+ }
2133+ if (r)
2134+ mpz_swap (tr, r);
2135+
2136+ mpz_clear (tr);
2137+
2138+ return rn != 0;
2139+ }
2140+}
2141+
2142+void
2143+mpz_cdiv_qr (mpz_t q, mpz_t r, const mpz_t n, const mpz_t d)
2144+{
2145+ mpz_div_qr (q, r, n, d, GMP_DIV_CEIL);
2146+}
2147+
2148+void
2149+mpz_fdiv_qr (mpz_t q, mpz_t r, const mpz_t n, const mpz_t d)
2150+{
2151+ mpz_div_qr (q, r, n, d, GMP_DIV_FLOOR);
2152+}
2153+
2154+void
2155+mpz_tdiv_qr (mpz_t q, mpz_t r, const mpz_t n, const mpz_t d)
2156+{
2157+ mpz_div_qr (q, r, n, d, GMP_DIV_TRUNC);
2158+}
2159+
2160+void
2161+mpz_cdiv_q (mpz_t q, const mpz_t n, const mpz_t d)
2162+{
2163+ mpz_div_qr (q, NULL, n, d, GMP_DIV_CEIL);
2164+}
2165+
2166+void
2167+mpz_fdiv_q (mpz_t q, const mpz_t n, const mpz_t d)
2168+{
2169+ mpz_div_qr (q, NULL, n, d, GMP_DIV_FLOOR);
2170+}
2171+
2172+void
2173+mpz_tdiv_q (mpz_t q, const mpz_t n, const mpz_t d)
2174+{
2175+ mpz_div_qr (q, NULL, n, d, GMP_DIV_TRUNC);
2176+}
2177+
2178+void
2179+mpz_cdiv_r (mpz_t r, const mpz_t n, const mpz_t d)
2180+{
2181+ mpz_div_qr (NULL, r, n, d, GMP_DIV_CEIL);
2182+}
2183+
2184+void
2185+mpz_fdiv_r (mpz_t r, const mpz_t n, const mpz_t d)
2186+{
2187+ mpz_div_qr (NULL, r, n, d, GMP_DIV_FLOOR);
2188+}
2189+
2190+void
2191+mpz_tdiv_r (mpz_t r, const mpz_t n, const mpz_t d)
2192+{
2193+ mpz_div_qr (NULL, r, n, d, GMP_DIV_TRUNC);
2194+}
2195+
2196+void
2197+mpz_mod (mpz_t r, const mpz_t n, const mpz_t d)
2198+{
2199+ mpz_div_qr (NULL, r, n, d, d->_mp_size >= 0 ? GMP_DIV_FLOOR : GMP_DIV_CEIL);
2200+}
2201+
2202+static void
2203+mpz_div_q_2exp (mpz_t q, const mpz_t u, mp_bitcnt_t bit_index,
2204+ enum mpz_div_round_mode mode)
2205+{
2206+ mp_size_t un, qn;
2207+ mp_size_t limb_cnt;
2208+ mp_ptr qp;
2209+ int adjust;
2210+
2211+ un = u->_mp_size;
2212+ if (un == 0)
2213+ {
2214+ q->_mp_size = 0;
2215+ return;
2216+ }
2217+ limb_cnt = bit_index / GMP_LIMB_BITS;
2218+ qn = GMP_ABS (un) - limb_cnt;
2219+ bit_index %= GMP_LIMB_BITS;
2220+
2221+ if (mode == ((un > 0) ? GMP_DIV_CEIL : GMP_DIV_FLOOR)) /* un != 0 here. */
2222+ /* Note: Below, the final indexing at limb_cnt is valid because at
2223+ that point we have qn > 0. */
2224+ adjust = (qn <= 0
2225+ || !mpn_zero_p (u->_mp_d, limb_cnt)
2226+ || (u->_mp_d[limb_cnt]
2227+ & (((mp_limb_t) 1 << bit_index) - 1)));
2228+ else
2229+ adjust = 0;
2230+
2231+ if (qn <= 0)
2232+ qn = 0;
2233+
2234+ else
2235+ {
2236+ qp = MPZ_REALLOC (q, qn);
2237+
2238+ if (bit_index != 0)
2239+ {
2240+ mpn_rshift (qp, u->_mp_d + limb_cnt, qn, bit_index);
2241+ qn -= qp[qn - 1] == 0;
2242+ }
2243+ else
2244+ {
2245+ mpn_copyi (qp, u->_mp_d + limb_cnt, qn);
2246+ }
2247+ }
2248+
2249+ q->_mp_size = qn;
2250+
2251+ if (adjust)
2252+ mpz_add_ui (q, q, 1);
2253+ if (un < 0)
2254+ mpz_neg (q, q);
2255+}
2256+
2257+static void
2258+mpz_div_r_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t bit_index,
2259+ enum mpz_div_round_mode mode)
2260+{
2261+ mp_size_t us, un, rn;
2262+ mp_ptr rp;
2263+ mp_limb_t mask;
2264+
2265+ us = u->_mp_size;
2266+ if (us == 0 || bit_index == 0)
2267+ {
2268+ r->_mp_size = 0;
2269+ return;
2270+ }
2271+ rn = (bit_index + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
2272+ assert (rn > 0);
2273+
2274+ rp = MPZ_REALLOC (r, rn);
2275+ un = GMP_ABS (us);
2276+
2277+ mask = GMP_LIMB_MAX >> (rn * GMP_LIMB_BITS - bit_index);
2278+
2279+ if (rn > un)
2280+ {
2281+ /* Quotient (with truncation) is zero, and remainder is
2282+ non-zero */
2283+ if (mode == ((us > 0) ? GMP_DIV_CEIL : GMP_DIV_FLOOR)) /* us != 0 here. */
2284+ {
2285+ /* Have to negate and sign extend. */
2286+ mp_size_t i;
2287+ mp_limb_t cy;
2288+
2289+ for (cy = 1, i = 0; i < un; i++)
2290+ {
2291+ mp_limb_t s = ~u->_mp_d[i] + cy;
2292+ cy = s < cy;
2293+ rp[i] = s;
2294+ }
2295+ assert (cy == 0);
2296+ for (; i < rn - 1; i++)
2297+ rp[i] = GMP_LIMB_MAX;
2298+
2299+ rp[rn-1] = mask;
2300+ us = -us;
2301+ }
2302+ else
2303+ {
2304+ /* Just copy */
2305+ if (r != u)
2306+ mpn_copyi (rp, u->_mp_d, un);
2307+
2308+ rn = un;
2309+ }
2310+ }
2311+ else
2312+ {
2313+ if (r != u)
2314+ mpn_copyi (rp, u->_mp_d, rn - 1);
2315+
2316+ rp[rn-1] = u->_mp_d[rn-1] & mask;
2317+
2318+ if (mode == ((us > 0) ? GMP_DIV_CEIL : GMP_DIV_FLOOR)) /* us != 0 here. */
2319+ {
2320+ /* If r != 0, compute 2^{bit_count} - r. */
2321+ mp_size_t i;
2322+
2323+ for (i = 0; i < rn && rp[i] == 0; i++)
2324+ ;
2325+ if (i < rn)
2326+ {
2327+ /* r > 0, need to flip sign. */
2328+ rp[i] = ~rp[i] + 1;
2329+ while (++i < rn)
2330+ rp[i] = ~rp[i];
2331+
2332+ rp[rn-1] &= mask;
2333+
2334+ /* us is not used for anything else, so we can modify it
2335+ here to indicate flipped sign. */
2336+ us = -us;
2337+ }
2338+ }
2339+ }
2340+ rn = mpn_normalized_size (rp, rn);
2341+ r->_mp_size = us < 0 ? -rn : rn;
2342+}
2343+
2344+void
2345+mpz_cdiv_q_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt)
2346+{
2347+ mpz_div_q_2exp (r, u, cnt, GMP_DIV_CEIL);
2348+}
2349+
2350+void
2351+mpz_fdiv_q_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt)
2352+{
2353+ mpz_div_q_2exp (r, u, cnt, GMP_DIV_FLOOR);
2354+}
2355+
2356+void
2357+mpz_tdiv_q_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt)
2358+{
2359+ mpz_div_q_2exp (r, u, cnt, GMP_DIV_TRUNC);
2360+}
2361+
2362+void
2363+mpz_cdiv_r_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt)
2364+{
2365+ mpz_div_r_2exp (r, u, cnt, GMP_DIV_CEIL);
2366+}
2367+
2368+void
2369+mpz_fdiv_r_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt)
2370+{
2371+ mpz_div_r_2exp (r, u, cnt, GMP_DIV_FLOOR);
2372+}
2373+
2374+void
2375+mpz_tdiv_r_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t cnt)
2376+{
2377+ mpz_div_r_2exp (r, u, cnt, GMP_DIV_TRUNC);
2378+}
2379+
2380+void
2381+mpz_divexact (mpz_t q, const mpz_t n, const mpz_t d)
2382+{
2383+ gmp_assert_nocarry (mpz_div_qr (q, NULL, n, d, GMP_DIV_TRUNC));
2384+}
2385+
2386+int
2387+mpz_divisible_p (const mpz_t n, const mpz_t d)
2388+{
2389+ return mpz_div_qr (NULL, NULL, n, d, GMP_DIV_TRUNC) == 0;
2390+}
2391+
2392+static unsigned long
2393+mpz_div_qr_ui (mpz_t q, mpz_t r,
2394+ const mpz_t n, unsigned long d, enum mpz_div_round_mode mode)
2395+{
2396+ mp_size_t ns, qn;
2397+ mp_ptr qp;
2398+ mp_limb_t rl;
2399+ mp_size_t rs;
2400+
2401+ ns = n->_mp_size;
2402+ if (ns == 0)
2403+ {
2404+ if (q)
2405+ q->_mp_size = 0;
2406+ if (r)
2407+ r->_mp_size = 0;
2408+ return 0;
2409+ }
2410+
2411+ qn = GMP_ABS (ns);
2412+ if (q)
2413+ qp = MPZ_REALLOC (q, qn);
2414+ else
2415+ qp = NULL;
2416+
2417+ rl = mpn_div_qr_1 (qp, n->_mp_d, qn, d);
2418+ assert (rl < d);
2419+
2420+ rs = rl > 0;
2421+ rs = (ns < 0) ? -rs : rs;
2422+
2423+ if (rl > 0 && ( (mode == GMP_DIV_FLOOR && ns < 0)
2424+ || (mode == GMP_DIV_CEIL && ns >= 0)))
2425+ {
2426+ if (q)
2427+ gmp_assert_nocarry (mpn_add_1 (qp, qp, qn, 1));
2428+ rl = d - rl;
2429+ rs = -rs;
2430+ }
2431+
2432+ if (r)
2433+ {
2434+ r->_mp_d[0] = rl;
2435+ r->_mp_size = rs;
2436+ }
2437+ if (q)
2438+ {
2439+ qn -= (qp[qn-1] == 0);
2440+ assert (qn == 0 || qp[qn-1] > 0);
2441+
2442+ q->_mp_size = (ns < 0) ? - qn : qn;
2443+ }
2444+
2445+ return rl;
2446+}
2447+
2448+unsigned long
2449+mpz_cdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, unsigned long d)
2450+{
2451+ return mpz_div_qr_ui (q, r, n, d, GMP_DIV_CEIL);
2452+}
2453+
2454+unsigned long
2455+mpz_fdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, unsigned long d)
2456+{
2457+ return mpz_div_qr_ui (q, r, n, d, GMP_DIV_FLOOR);
2458+}
2459+
2460+unsigned long
2461+mpz_tdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, unsigned long d)
2462+{
2463+ return mpz_div_qr_ui (q, r, n, d, GMP_DIV_TRUNC);
2464+}
2465+
2466+unsigned long
2467+mpz_cdiv_q_ui (mpz_t q, const mpz_t n, unsigned long d)
2468+{
2469+ return mpz_div_qr_ui (q, NULL, n, d, GMP_DIV_CEIL);
2470+}
2471+
2472+unsigned long
2473+mpz_fdiv_q_ui (mpz_t q, const mpz_t n, unsigned long d)
2474+{
2475+ return mpz_div_qr_ui (q, NULL, n, d, GMP_DIV_FLOOR);
2476+}
2477+
2478+unsigned long
2479+mpz_tdiv_q_ui (mpz_t q, const mpz_t n, unsigned long d)
2480+{
2481+ return mpz_div_qr_ui (q, NULL, n, d, GMP_DIV_TRUNC);
2482+}
2483+
2484+unsigned long
2485+mpz_cdiv_r_ui (mpz_t r, const mpz_t n, unsigned long d)
2486+{
2487+ return mpz_div_qr_ui (NULL, r, n, d, GMP_DIV_CEIL);
2488+}
2489+unsigned long
2490+mpz_fdiv_r_ui (mpz_t r, const mpz_t n, unsigned long d)
2491+{
2492+ return mpz_div_qr_ui (NULL, r, n, d, GMP_DIV_FLOOR);
2493+}
2494+unsigned long
2495+mpz_tdiv_r_ui (mpz_t r, const mpz_t n, unsigned long d)
2496+{
2497+ return mpz_div_qr_ui (NULL, r, n, d, GMP_DIV_TRUNC);
2498+}
2499+
2500+unsigned long
2501+mpz_cdiv_ui (const mpz_t n, unsigned long d)
2502+{
2503+ return mpz_div_qr_ui (NULL, NULL, n, d, GMP_DIV_CEIL);
2504+}
2505+
2506+unsigned long
2507+mpz_fdiv_ui (const mpz_t n, unsigned long d)
2508+{
2509+ return mpz_div_qr_ui (NULL, NULL, n, d, GMP_DIV_FLOOR);
2510+}
2511+
2512+unsigned long
2513+mpz_tdiv_ui (const mpz_t n, unsigned long d)
2514+{
2515+ return mpz_div_qr_ui (NULL, NULL, n, d, GMP_DIV_TRUNC);
2516+}
2517+
2518+unsigned long
2519+mpz_mod_ui (mpz_t r, const mpz_t n, unsigned long d)
2520+{
2521+ return mpz_div_qr_ui (NULL, r, n, d, GMP_DIV_FLOOR);
2522+}
2523+
2524+void
2525+mpz_divexact_ui (mpz_t q, const mpz_t n, unsigned long d)
2526+{
2527+ gmp_assert_nocarry (mpz_div_qr_ui (q, NULL, n, d, GMP_DIV_TRUNC));
2528+}
2529+
2530+int
2531+mpz_divisible_ui_p (const mpz_t n, unsigned long d)
2532+{
2533+ return mpz_div_qr_ui (NULL, NULL, n, d, GMP_DIV_TRUNC) == 0;
2534+}
2535+
2536+
2537+/* GCD */
2538+static mp_limb_t
2539+mpn_gcd_11 (mp_limb_t u, mp_limb_t v)
2540+{
2541+ unsigned shift;
2542+
2543+ assert ( (u | v) > 0);
2544+
2545+ if (u == 0)
2546+ return v;
2547+ else if (v == 0)
2548+ return u;
2549+
2550+ gmp_ctz (shift, u | v);
2551+
2552+ u >>= shift;
2553+ v >>= shift;
2554+
2555+ if ( (u & 1) == 0)
2556+ MP_LIMB_T_SWAP (u, v);
2557+
2558+ while ( (v & 1) == 0)
2559+ v >>= 1;
2560+
2561+ while (u != v)
2562+ {
2563+ if (u > v)
2564+ {
2565+ u -= v;
2566+ do
2567+ u >>= 1;
2568+ while ( (u & 1) == 0);
2569+ }
2570+ else
2571+ {
2572+ v -= u;
2573+ do
2574+ v >>= 1;
2575+ while ( (v & 1) == 0);
2576+ }
2577+ }
2578+ return u << shift;
2579+}
2580+
2581+unsigned long
2582+mpz_gcd_ui (mpz_t g, const mpz_t u, unsigned long v)
2583+{
2584+ mp_size_t un;
2585+
2586+ if (v == 0)
2587+ {
2588+ if (g)
2589+ mpz_abs (g, u);
2590+ }
2591+ else
2592+ {
2593+ un = GMP_ABS (u->_mp_size);
2594+ if (un != 0)
2595+ v = mpn_gcd_11 (mpn_div_qr_1 (NULL, u->_mp_d, un, v), v);
2596+
2597+ if (g)
2598+ mpz_set_ui (g, v);
2599+ }
2600+
2601+ return v;
2602+}
2603+
2604+static mp_bitcnt_t
2605+mpz_make_odd (mpz_t r)
2606+{
2607+ mp_bitcnt_t shift;
2608+
2609+ assert (r->_mp_size > 0);
2610+ /* Count trailing zeros, equivalent to mpn_scan1, because we know that there is a 1 */
2611+ shift = mpn_common_scan (r->_mp_d[0], 0, r->_mp_d, 0, 0);
2612+ mpz_tdiv_q_2exp (r, r, shift);
2613+
2614+ return shift;
2615+}
2616+
2617+void
2618+mpz_gcd (mpz_t g, const mpz_t u, const mpz_t v)
2619+{
2620+ mpz_t tu, tv;
2621+ mp_bitcnt_t uz, vz, gz;
2622+
2623+ if (u->_mp_size == 0)
2624+ {
2625+ mpz_abs (g, v);
2626+ return;
2627+ }
2628+ if (v->_mp_size == 0)
2629+ {
2630+ mpz_abs (g, u);
2631+ return;
2632+ }
2633+
2634+ mpz_init (tu);
2635+ mpz_init (tv);
2636+
2637+ mpz_abs (tu, u);
2638+ uz = mpz_make_odd (tu);
2639+ mpz_abs (tv, v);
2640+ vz = mpz_make_odd (tv);
2641+ gz = GMP_MIN (uz, vz);
2642+
2643+ if (tu->_mp_size < tv->_mp_size)
2644+ mpz_swap (tu, tv);
2645+
2646+ mpz_tdiv_r (tu, tu, tv);
2647+ if (tu->_mp_size == 0)
2648+ {
2649+ mpz_swap (g, tv);
2650+ }
2651+ else
2652+ for (;;)
2653+ {
2654+ int c;
2655+
2656+ mpz_make_odd (tu);
2657+ c = mpz_cmp (tu, tv);
2658+ if (c == 0)
2659+ {
2660+ mpz_swap (g, tu);
2661+ break;
2662+ }
2663+ if (c < 0)
2664+ mpz_swap (tu, tv);
2665+
2666+ if (tv->_mp_size == 1)
2667+ {
2668+ mp_limb_t vl = tv->_mp_d[0];
2669+ mp_limb_t ul = mpz_tdiv_ui (tu, vl);
2670+ mpz_set_ui (g, mpn_gcd_11 (ul, vl));
2671+ break;
2672+ }
2673+ mpz_sub (tu, tu, tv);
2674+ }
2675+ mpz_clear (tu);
2676+ mpz_clear (tv);
2677+ mpz_mul_2exp (g, g, gz);
2678+}
2679+
2680+void
2681+mpz_gcdext (mpz_t g, mpz_t s, mpz_t t, const mpz_t u, const mpz_t v)
2682+{
2683+ mpz_t tu, tv, s0, s1, t0, t1;
2684+ mp_bitcnt_t uz, vz, gz;
2685+ mp_bitcnt_t power;
2686+
2687+ if (u->_mp_size == 0)
2688+ {
2689+ /* g = 0 u + sgn(v) v */
2690+ signed long sign = mpz_sgn (v);
2691+ mpz_abs (g, v);
2692+ if (s)
2693+ mpz_set_ui (s, 0);
2694+ if (t)
2695+ mpz_set_si (t, sign);
2696+ return;
2697+ }
2698+
2699+ if (v->_mp_size == 0)
2700+ {
2701+ /* g = sgn(u) u + 0 v */
2702+ signed long sign = mpz_sgn (u);
2703+ mpz_abs (g, u);
2704+ if (s)
2705+ mpz_set_si (s, sign);
2706+ if (t)
2707+ mpz_set_ui (t, 0);
2708+ return;
2709+ }
2710+
2711+ mpz_init (tu);
2712+ mpz_init (tv);
2713+ mpz_init (s0);
2714+ mpz_init (s1);
2715+ mpz_init (t0);
2716+ mpz_init (t1);
2717+
2718+ mpz_abs (tu, u);
2719+ uz = mpz_make_odd (tu);
2720+ mpz_abs (tv, v);
2721+ vz = mpz_make_odd (tv);
2722+ gz = GMP_MIN (uz, vz);
2723+
2724+ uz -= gz;
2725+ vz -= gz;
2726+
2727+ /* Cofactors corresponding to odd gcd. gz handled later. */
2728+ if (tu->_mp_size < tv->_mp_size)
2729+ {
2730+ mpz_swap (tu, tv);
2731+ MPZ_SRCPTR_SWAP (u, v);
2732+ MPZ_PTR_SWAP (s, t);
2733+ MP_BITCNT_T_SWAP (uz, vz);
2734+ }
2735+
2736+ /* Maintain
2737+ *
2738+ * u = t0 tu + t1 tv
2739+ * v = s0 tu + s1 tv
2740+ *
2741+ * where u and v denote the inputs with common factors of two
2742+ * eliminated, and det (s0, t0; s1, t1) = 2^p. Then
2743+ *
2744+ * 2^p tu = s1 u - t1 v
2745+ * 2^p tv = -s0 u + t0 v
2746+ */
2747+
2748+ /* After initial division, tu = q tv + tu', we have
2749+ *
2750+ * u = 2^uz (tu' + q tv)
2751+ * v = 2^vz tv
2752+ *
2753+ * or
2754+ *
2755+ * t0 = 2^uz, t1 = 2^uz q
2756+ * s0 = 0, s1 = 2^vz
2757+ */
2758+
2759+ mpz_setbit (t0, uz);
2760+ mpz_tdiv_qr (t1, tu, tu, tv);
2761+ mpz_mul_2exp (t1, t1, uz);
2762+
2763+ mpz_setbit (s1, vz);
2764+ power = uz + vz;
2765+
2766+ if (tu->_mp_size > 0)
2767+ {
2768+ mp_bitcnt_t shift;
2769+ shift = mpz_make_odd (tu);
2770+ mpz_mul_2exp (t0, t0, shift);
2771+ mpz_mul_2exp (s0, s0, shift);
2772+ power += shift;
2773+
2774+ for (;;)
2775+ {
2776+ int c;
2777+ c = mpz_cmp (tu, tv);
2778+ if (c == 0)
2779+ break;
2780+
2781+ if (c < 0)
2782+ {
2783+ /* tv = tv' + tu
2784+ *
2785+ * u = t0 tu + t1 (tv' + tu) = (t0 + t1) tu + t1 tv'
2786+ * v = s0 tu + s1 (tv' + tu) = (s0 + s1) tu + s1 tv' */
2787+
2788+ mpz_sub (tv, tv, tu);
2789+ mpz_add (t0, t0, t1);
2790+ mpz_add (s0, s0, s1);
2791+
2792+ shift = mpz_make_odd (tv);
2793+ mpz_mul_2exp (t1, t1, shift);
2794+ mpz_mul_2exp (s1, s1, shift);
2795+ }
2796+ else
2797+ {
2798+ mpz_sub (tu, tu, tv);
2799+ mpz_add (t1, t0, t1);
2800+ mpz_add (s1, s0, s1);
2801+
2802+ shift = mpz_make_odd (tu);
2803+ mpz_mul_2exp (t0, t0, shift);
2804+ mpz_mul_2exp (s0, s0, shift);
2805+ }
2806+ power += shift;
2807+ }
2808+ }
2809+
2810+ /* Now tv = odd part of gcd, and -s0 and t0 are corresponding
2811+ cofactors. */
2812+
2813+ mpz_mul_2exp (tv, tv, gz);
2814+ mpz_neg (s0, s0);
2815+
2816+ /* 2^p g = s0 u + t0 v. Eliminate one factor of two at a time. To
2817+ adjust cofactors, we need u / g and v / g */
2818+
2819+ mpz_divexact (s1, v, tv);
2820+ mpz_abs (s1, s1);
2821+ mpz_divexact (t1, u, tv);
2822+ mpz_abs (t1, t1);
2823+
2824+ while (power-- > 0)
2825+ {
2826+ /* s0 u + t0 v = (s0 - v/g) u - (t0 + u/g) v */
2827+ if (mpz_odd_p (s0) || mpz_odd_p (t0))
2828+ {
2829+ mpz_sub (s0, s0, s1);
2830+ mpz_add (t0, t0, t1);
2831+ }
2832+ mpz_divexact_ui (s0, s0, 2);
2833+ mpz_divexact_ui (t0, t0, 2);
2834+ }
2835+
2836+ /* Arrange so that |s| < |u| / 2g */
2837+ mpz_add (s1, s0, s1);
2838+ if (mpz_cmpabs (s0, s1) > 0)
2839+ {
2840+ mpz_swap (s0, s1);
2841+ mpz_sub (t0, t0, t1);
2842+ }
2843+ if (u->_mp_size < 0)
2844+ mpz_neg (s0, s0);
2845+ if (v->_mp_size < 0)
2846+ mpz_neg (t0, t0);
2847+
2848+ mpz_swap (g, tv);
2849+ if (s)
2850+ mpz_swap (s, s0);
2851+ if (t)
2852+ mpz_swap (t, t0);
2853+
2854+ mpz_clear (tu);
2855+ mpz_clear (tv);
2856+ mpz_clear (s0);
2857+ mpz_clear (s1);
2858+ mpz_clear (t0);
2859+ mpz_clear (t1);
2860+}
2861+
2862+void
2863+mpz_lcm (mpz_t r, const mpz_t u, const mpz_t v)
2864+{
2865+ mpz_t g;
2866+
2867+ if (u->_mp_size == 0 || v->_mp_size == 0)
2868+ {
2869+ r->_mp_size = 0;
2870+ return;
2871+ }
2872+
2873+ mpz_init (g);
2874+
2875+ mpz_gcd (g, u, v);
2876+ mpz_divexact (g, u, g);
2877+ mpz_mul (r, g, v);
2878+
2879+ mpz_clear (g);
2880+ mpz_abs (r, r);
2881+}
2882+
2883+void
2884+mpz_lcm_ui (mpz_t r, const mpz_t u, unsigned long v)
2885+{
2886+ if (v == 0 || u->_mp_size == 0)
2887+ {
2888+ r->_mp_size = 0;
2889+ return;
2890+ }
2891+
2892+ v /= mpz_gcd_ui (NULL, u, v);
2893+ mpz_mul_ui (r, u, v);
2894+
2895+ mpz_abs (r, r);
2896+}
2897+
2898+int
2899+mpz_invert (mpz_t r, const mpz_t u, const mpz_t m)
2900+{
2901+ mpz_t g, tr;
2902+ int invertible;
2903+
2904+ if (u->_mp_size == 0 || mpz_cmpabs_ui (m, 1) <= 0)
2905+ return 0;
2906+
2907+ mpz_init (g);
2908+ mpz_init (tr);
2909+
2910+ mpz_gcdext (g, tr, NULL, u, m);
2911+ invertible = (mpz_cmp_ui (g, 1) == 0);
2912+
2913+ if (invertible)
2914+ {
2915+ if (tr->_mp_size < 0)
2916+ {
2917+ if (m->_mp_size >= 0)
2918+ mpz_add (tr, tr, m);
2919+ else
2920+ mpz_sub (tr, tr, m);
2921+ }
2922+ mpz_swap (r, tr);
2923+ }
2924+
2925+ mpz_clear (g);
2926+ mpz_clear (tr);
2927+ return invertible;
2928+}
2929+
2930+
2931+/* Higher level operations (sqrt, pow and root) */
2932+
2933+void
2934+mpz_pow_ui (mpz_t r, const mpz_t b, unsigned long e)
2935+{
2936+ unsigned long bit;
2937+ mpz_t tr;
2938+ mpz_init_set_ui (tr, 1);
2939+
2940+ bit = GMP_ULONG_HIGHBIT;
2941+ do
2942+ {
2943+ mpz_mul (tr, tr, tr);
2944+ if (e & bit)
2945+ mpz_mul (tr, tr, b);
2946+ bit >>= 1;
2947+ }
2948+ while (bit > 0);
2949+
2950+ mpz_swap (r, tr);
2951+ mpz_clear (tr);
2952+}
2953+
2954+void
2955+mpz_ui_pow_ui (mpz_t r, unsigned long blimb, unsigned long e)
2956+{
2957+ mpz_t b;
2958+ mpz_init_set_ui (b, blimb);
2959+ mpz_pow_ui (r, b, e);
2960+ mpz_clear (b);
2961+}
2962+
2963+void
2964+mpz_powm (mpz_t r, const mpz_t b, const mpz_t e, const mpz_t m)
2965+{
2966+ mpz_t tr;
2967+ mpz_t base;
2968+ mp_size_t en, mn;
2969+ mp_srcptr mp;
2970+ struct gmp_div_inverse minv;
2971+ unsigned shift;
2972+ mp_ptr tp = NULL;
2973+
2974+ en = GMP_ABS (e->_mp_size);
2975+ mn = GMP_ABS (m->_mp_size);
2976+ if (mn == 0)
2977+ gmp_die ("mpz_powm: Zero modulo.");
2978+
2979+ if (en == 0)
2980+ {
2981+ mpz_set_ui (r, 1);
2982+ return;
2983+ }
2984+
2985+ mp = m->_mp_d;
2986+ mpn_div_qr_invert (&minv, mp, mn);
2987+ shift = minv.shift;
2988+
2989+ if (shift > 0)
2990+ {
2991+ /* To avoid shifts, we do all our reductions, except the final
2992+ one, using a *normalized* m. */
2993+ minv.shift = 0;
2994+
2995+ tp = gmp_xalloc_limbs (mn);
2996+ gmp_assert_nocarry (mpn_lshift (tp, mp, mn, shift));
2997+ mp = tp;
2998+ }
2999+
3000+ mpz_init (base);
3001+
3002+ if (e->_mp_size < 0)
3003+ {
3004+ if (!mpz_invert (base, b, m))
3005+ gmp_die ("mpz_powm: Negative exponent and non-invertible base.");
3006+ }
3007+ else
3008+ {
3009+ mp_size_t bn;
3010+ mpz_abs (base, b);
3011+
3012+ bn = base->_mp_size;
3013+ if (bn >= mn)
3014+ {
3015+ mpn_div_qr_preinv (NULL, base->_mp_d, base->_mp_size, mp, mn, &minv);
3016+ bn = mn;
3017+ }
3018+
3019+ /* We have reduced the absolute value. Now take care of the
3020+ sign. Note that we get zero represented non-canonically as
3021+ m. */
3022+ if (b->_mp_size < 0)
3023+ {
3024+ mp_ptr bp = MPZ_REALLOC (base, mn);
3025+ gmp_assert_nocarry (mpn_sub (bp, mp, mn, bp, bn));
3026+ bn = mn;
3027+ }
3028+ base->_mp_size = mpn_normalized_size (base->_mp_d, bn);
3029+ }
3030+ mpz_init_set_ui (tr, 1);
3031+
3032+ while (en-- > 0)
3033+ {
3034+ mp_limb_t w = e->_mp_d[en];
3035+ mp_limb_t bit;
3036+
3037+ bit = GMP_LIMB_HIGHBIT;
3038+ do
3039+ {
3040+ mpz_mul (tr, tr, tr);
3041+ if (w & bit)
3042+ mpz_mul (tr, tr, base);
3043+ if (tr->_mp_size > mn)
3044+ {
3045+ mpn_div_qr_preinv (NULL, tr->_mp_d, tr->_mp_size, mp, mn, &minv);
3046+ tr->_mp_size = mpn_normalized_size (tr->_mp_d, mn);
3047+ }
3048+ bit >>= 1;
3049+ }
3050+ while (bit > 0);
3051+ }
3052+
3053+ /* Final reduction */
3054+ if (tr->_mp_size >= mn)
3055+ {
3056+ minv.shift = shift;
3057+ mpn_div_qr_preinv (NULL, tr->_mp_d, tr->_mp_size, mp, mn, &minv);
3058+ tr->_mp_size = mpn_normalized_size (tr->_mp_d, mn);
3059+ }
3060+ if (tp)
3061+ gmp_free (tp);
3062+
3063+ mpz_swap (r, tr);
3064+ mpz_clear (tr);
3065+ mpz_clear (base);
3066+}
3067+
3068+void
3069+mpz_powm_ui (mpz_t r, const mpz_t b, unsigned long elimb, const mpz_t m)
3070+{
3071+ mpz_t e;
3072+ mpz_init_set_ui (e, elimb);
3073+ mpz_powm (r, b, e, m);
3074+ mpz_clear (e);
3075+}
3076+
3077+/* x=trunc(y^(1/z)), r=y-x^z */
3078+void
3079+mpz_rootrem (mpz_t x, mpz_t r, const mpz_t y, unsigned long z)
3080+{
3081+ int sgn;
3082+ mpz_t t, u;
3083+
3084+ sgn = y->_mp_size < 0;
3085+ if ((~z & sgn) != 0)
3086+ gmp_die ("mpz_rootrem: Negative argument, with even root.");
3087+ if (z == 0)
3088+ gmp_die ("mpz_rootrem: Zeroth root.");
3089+
3090+ if (mpz_cmpabs_ui (y, 1) <= 0) {
3091+ mpz_set (x, y);
3092+ if (r)
3093+ r->_mp_size = 0;
3094+ return;
3095+ }
3096+
3097+ mpz_init (u);
3098+ {
3099+ mp_bitcnt_t tb;
3100+ tb = mpz_sizeinbase (y, 2) / z + 1;
3101+ mpz_init2 (t, tb);
3102+ mpz_setbit (t, tb);
3103+ }
3104+
3105+ if (z == 2) /* simplify sqrt loop: z-1 == 1 */
3106+ do {
3107+ mpz_swap (u, t); /* u = x */
3108+ mpz_tdiv_q (t, y, u); /* t = y/x */
3109+ mpz_add (t, t, u); /* t = y/x + x */
3110+ mpz_tdiv_q_2exp (t, t, 1); /* x'= (y/x + x)/2 */
3111+ } while (mpz_cmpabs (t, u) < 0); /* |x'| < |x| */
3112+ else /* z != 2 */ {
3113+ mpz_t v;
3114+
3115+ mpz_init (v);
3116+ if (sgn)
3117+ mpz_neg (t, t);
3118+
3119+ do {
3120+ mpz_swap (u, t); /* u = x */
3121+ mpz_pow_ui (t, u, z - 1); /* t = x^(z-1) */
3122+ mpz_tdiv_q (t, y, t); /* t = y/x^(z-1) */
3123+ mpz_mul_ui (v, u, z - 1); /* v = x*(z-1) */
3124+ mpz_add (t, t, v); /* t = y/x^(z-1) + x*(z-1) */
3125+ mpz_tdiv_q_ui (t, t, z); /* x'=(y/x^(z-1) + x*(z-1))/z */
3126+ } while (mpz_cmpabs (t, u) < 0); /* |x'| < |x| */
3127+
3128+ mpz_clear (v);
3129+ }
3130+
3131+ if (r) {
3132+ mpz_pow_ui (t, u, z);
3133+ mpz_sub (r, y, t);
3134+ }
3135+ mpz_swap (x, u);
3136+ mpz_clear (u);
3137+ mpz_clear (t);
3138+}
3139+
3140+int
3141+mpz_root (mpz_t x, const mpz_t y, unsigned long z)
3142+{
3143+ int res;
3144+ mpz_t r;
3145+
3146+ mpz_init (r);
3147+ mpz_rootrem (x, r, y, z);
3148+ res = r->_mp_size == 0;
3149+ mpz_clear (r);
3150+
3151+ return res;
3152+}
3153+
3154+/* Compute s = floor(sqrt(u)) and r = u - s^2. Allows r == NULL */
3155+void
3156+mpz_sqrtrem (mpz_t s, mpz_t r, const mpz_t u)
3157+{
3158+ mpz_rootrem (s, r, u, 2);
3159+}
3160+
3161+void
3162+mpz_sqrt (mpz_t s, const mpz_t u)
3163+{
3164+ mpz_rootrem (s, NULL, u, 2);
3165+}
3166+
3167+
3168+/* Combinatorics */
3169+
3170+void
3171+mpz_fac_ui (mpz_t x, unsigned long n)
3172+{
3173+ mpz_set_ui (x, n + (n == 0));
3174+ for (;n > 2;)
3175+ mpz_mul_ui (x, x, --n);
3176+}
3177+
3178+void
3179+mpz_bin_uiui (mpz_t r, unsigned long n, unsigned long k)
3180+{
3181+ mpz_t t;
3182+
3183+ mpz_set_ui (r, k <= n);
3184+
3185+ if (k > (n >> 1))
3186+ k = (k <= n) ? n - k : 0;
3187+
3188+ mpz_init (t);
3189+ mpz_fac_ui (t, k);
3190+
3191+ for (; k > 0; k--)
3192+ mpz_mul_ui (r, r, n--);
3193+
3194+ mpz_divexact (r, r, t);
3195+ mpz_clear (t);
3196+}
3197+
3198+
3199+/* Logical operations and bit manipulation. */
3200+
3201+/* Numbers are treated as if represented in two's complement (and
3202+ infinitely sign extended). For a negative values we get the two's
3203+ complement from -x = ~x + 1, where ~ is bitwise complement.
3204+ Negation transforms
3205+
3206+ xxxx10...0
3207+
3208+ into
3209+
3210+ yyyy10...0
3211+
3212+ where yyyy is the bitwise complement of xxxx. So least significant
3213+ bits, up to and including the first one bit, are unchanged, and
3214+ the more significant bits are all complemented.
3215+
3216+ To change a bit from zero to one in a negative number, subtract the
3217+ corresponding power of two from the absolute value. This can never
3218+ underflow. To change a bit from one to zero, add the corresponding
3219+ power of two, and this might overflow. E.g., if x = -001111, the
3220+ two's complement is 110001. Clearing the least significant bit, we
3221+ get two's complement 110000, and -010000. */
3222+
3223+int
3224+mpz_tstbit (const mpz_t d, mp_bitcnt_t bit_index)
3225+{
3226+ mp_size_t limb_index;
3227+ unsigned shift;
3228+ mp_size_t ds;
3229+ mp_size_t dn;
3230+ mp_limb_t w;
3231+ int bit;
3232+
3233+ ds = d->_mp_size;
3234+ dn = GMP_ABS (ds);
3235+ limb_index = bit_index / GMP_LIMB_BITS;
3236+ if (limb_index >= dn)
3237+ return ds < 0;
3238+
3239+ shift = bit_index % GMP_LIMB_BITS;
3240+ w = d->_mp_d[limb_index];
3241+ bit = (w >> shift) & 1;
3242+
3243+ if (ds < 0)
3244+ {
3245+ /* d < 0. Check if any of the bits below is set: If so, our bit
3246+ must be complemented. */
3247+ if (shift > 0 && (w << (GMP_LIMB_BITS - shift)) > 0)
3248+ return bit ^ 1;
3249+ while (limb_index-- > 0)
3250+ if (d->_mp_d[limb_index] > 0)
3251+ return bit ^ 1;
3252+ }
3253+ return bit;
3254+}
3255+
3256+static void
3257+mpz_abs_add_bit (mpz_t d, mp_bitcnt_t bit_index)
3258+{
3259+ mp_size_t dn, limb_index;
3260+ mp_limb_t bit;
3261+ mp_ptr dp;
3262+
3263+ dn = GMP_ABS (d->_mp_size);
3264+
3265+ limb_index = bit_index / GMP_LIMB_BITS;
3266+ bit = (mp_limb_t) 1 << (bit_index % GMP_LIMB_BITS);
3267+
3268+ if (limb_index >= dn)
3269+ {
3270+ mp_size_t i;
3271+ /* The bit should be set outside of the end of the number.
3272+ We have to increase the size of the number. */
3273+ dp = MPZ_REALLOC (d, limb_index + 1);
3274+
3275+ dp[limb_index] = bit;
3276+ for (i = dn; i < limb_index; i++)
3277+ dp[i] = 0;
3278+ dn = limb_index + 1;
3279+ }
3280+ else
3281+ {
3282+ mp_limb_t cy;
3283+
3284+ dp = d->_mp_d;
3285+
3286+ cy = mpn_add_1 (dp + limb_index, dp + limb_index, dn - limb_index, bit);
3287+ if (cy > 0)
3288+ {
3289+ dp = MPZ_REALLOC (d, dn + 1);
3290+ dp[dn++] = cy;
3291+ }
3292+ }
3293+
3294+ d->_mp_size = (d->_mp_size < 0) ? - dn : dn;
3295+}
3296+
3297+static void
3298+mpz_abs_sub_bit (mpz_t d, mp_bitcnt_t bit_index)
3299+{
3300+ mp_size_t dn, limb_index;
3301+ mp_ptr dp;
3302+ mp_limb_t bit;
3303+
3304+ dn = GMP_ABS (d->_mp_size);
3305+ dp = d->_mp_d;
3306+
3307+ limb_index = bit_index / GMP_LIMB_BITS;
3308+ bit = (mp_limb_t) 1 << (bit_index % GMP_LIMB_BITS);
3309+
3310+ assert (limb_index < dn);
3311+
3312+ gmp_assert_nocarry (mpn_sub_1 (dp + limb_index, dp + limb_index,
3313+ dn - limb_index, bit));
3314+ dn -= (dp[dn-1] == 0);
3315+ d->_mp_size = (d->_mp_size < 0) ? - dn : dn;
3316+}
3317+
3318+void
3319+mpz_setbit (mpz_t d, mp_bitcnt_t bit_index)
3320+{
3321+ if (!mpz_tstbit (d, bit_index))
3322+ {
3323+ if (d->_mp_size >= 0)
3324+ mpz_abs_add_bit (d, bit_index);
3325+ else
3326+ mpz_abs_sub_bit (d, bit_index);
3327+ }
3328+}
3329+
3330+void
3331+mpz_clrbit (mpz_t d, mp_bitcnt_t bit_index)
3332+{
3333+ if (mpz_tstbit (d, bit_index))
3334+ {
3335+ if (d->_mp_size >= 0)
3336+ mpz_abs_sub_bit (d, bit_index);
3337+ else
3338+ mpz_abs_add_bit (d, bit_index);
3339+ }
3340+}
3341+
3342+void
3343+mpz_combit (mpz_t d, mp_bitcnt_t bit_index)
3344+{
3345+ if (mpz_tstbit (d, bit_index) ^ (d->_mp_size < 0))
3346+ mpz_abs_sub_bit (d, bit_index);
3347+ else
3348+ mpz_abs_add_bit (d, bit_index);
3349+}
3350+
3351+void
3352+mpz_com (mpz_t r, const mpz_t u)
3353+{
3354+ mpz_neg (r, u);
3355+ mpz_sub_ui (r, r, 1);
3356+}
3357+
3358+void
3359+mpz_and (mpz_t r, const mpz_t u, const mpz_t v)
3360+{
3361+ mp_size_t un, vn, rn, i;
3362+ mp_ptr up, vp, rp;
3363+
3364+ mp_limb_t ux, vx, rx;
3365+ mp_limb_t uc, vc, rc;
3366+ mp_limb_t ul, vl, rl;
3367+
3368+ un = GMP_ABS (u->_mp_size);
3369+ vn = GMP_ABS (v->_mp_size);
3370+ if (un < vn)
3371+ {
3372+ MPZ_SRCPTR_SWAP (u, v);
3373+ MP_SIZE_T_SWAP (un, vn);
3374+ }
3375+ if (vn == 0)
3376+ {
3377+ r->_mp_size = 0;
3378+ return;
3379+ }
3380+
3381+ uc = u->_mp_size < 0;
3382+ vc = v->_mp_size < 0;
3383+ rc = uc & vc;
3384+
3385+ ux = -uc;
3386+ vx = -vc;
3387+ rx = -rc;
3388+
3389+ /* If the smaller input is positive, higher limbs don't matter. */
3390+ rn = vx ? un : vn;
3391+
3392+ rp = MPZ_REALLOC (r, rn + rc);
3393+
3394+ up = u->_mp_d;
3395+ vp = v->_mp_d;
3396+
3397+ i = 0;
3398+ do
3399+ {
3400+ ul = (up[i] ^ ux) + uc;
3401+ uc = ul < uc;
3402+
3403+ vl = (vp[i] ^ vx) + vc;
3404+ vc = vl < vc;
3405+
3406+ rl = ( (ul & vl) ^ rx) + rc;
3407+ rc = rl < rc;
3408+ rp[i] = rl;
3409+ }
3410+ while (++i < vn);
3411+ assert (vc == 0);
3412+
3413+ for (; i < rn; i++)
3414+ {
3415+ ul = (up[i] ^ ux) + uc;
3416+ uc = ul < uc;
3417+
3418+ rl = ( (ul & vx) ^ rx) + rc;
3419+ rc = rl < rc;
3420+ rp[i] = rl;
3421+ }
3422+ if (rc)
3423+ rp[rn++] = rc;
3424+ else
3425+ rn = mpn_normalized_size (rp, rn);
3426+
3427+ r->_mp_size = rx ? -rn : rn;
3428+}
3429+
3430+void
3431+mpz_ior (mpz_t r, const mpz_t u, const mpz_t v)
3432+{
3433+ mp_size_t un, vn, rn, i;
3434+ mp_ptr up, vp, rp;
3435+
3436+ mp_limb_t ux, vx, rx;
3437+ mp_limb_t uc, vc, rc;
3438+ mp_limb_t ul, vl, rl;
3439+
3440+ un = GMP_ABS (u->_mp_size);
3441+ vn = GMP_ABS (v->_mp_size);
3442+ if (un < vn)
3443+ {
3444+ MPZ_SRCPTR_SWAP (u, v);
3445+ MP_SIZE_T_SWAP (un, vn);
3446+ }
3447+ if (vn == 0)
3448+ {
3449+ mpz_set (r, u);
3450+ return;
3451+ }
3452+
3453+ uc = u->_mp_size < 0;
3454+ vc = v->_mp_size < 0;
3455+ rc = uc | vc;
3456+
3457+ ux = -uc;
3458+ vx = -vc;
3459+ rx = -rc;
3460+
3461+ /* If the smaller input is negative, by sign extension higher limbs
3462+ don't matter. */
3463+ rn = vx ? vn : un;
3464+
3465+ rp = MPZ_REALLOC (r, rn + rc);
3466+
3467+ up = u->_mp_d;
3468+ vp = v->_mp_d;
3469+
3470+ i = 0;
3471+ do
3472+ {
3473+ ul = (up[i] ^ ux) + uc;
3474+ uc = ul < uc;
3475+
3476+ vl = (vp[i] ^ vx) + vc;
3477+ vc = vl < vc;
3478+
3479+ rl = ( (ul | vl) ^ rx) + rc;
3480+ rc = rl < rc;
3481+ rp[i] = rl;
3482+ }
3483+ while (++i < vn);
3484+ assert (vc == 0);
3485+
3486+ for (; i < rn; i++)
3487+ {
3488+ ul = (up[i] ^ ux) + uc;
3489+ uc = ul < uc;
3490+
3491+ rl = ( (ul | vx) ^ rx) + rc;
3492+ rc = rl < rc;
3493+ rp[i] = rl;
3494+ }
3495+ if (rc)
3496+ rp[rn++] = rc;
3497+ else
3498+ rn = mpn_normalized_size (rp, rn);
3499+
3500+ r->_mp_size = rx ? -rn : rn;
3501+}
3502+
3503+void
3504+mpz_xor (mpz_t r, const mpz_t u, const mpz_t v)
3505+{
3506+ mp_size_t un, vn, i;
3507+ mp_ptr up, vp, rp;
3508+
3509+ mp_limb_t ux, vx, rx;
3510+ mp_limb_t uc, vc, rc;
3511+ mp_limb_t ul, vl, rl;
3512+
3513+ un = GMP_ABS (u->_mp_size);
3514+ vn = GMP_ABS (v->_mp_size);
3515+ if (un < vn)
3516+ {
3517+ MPZ_SRCPTR_SWAP (u, v);
3518+ MP_SIZE_T_SWAP (un, vn);
3519+ }
3520+ if (vn == 0)
3521+ {
3522+ mpz_set (r, u);
3523+ return;
3524+ }
3525+
3526+ uc = u->_mp_size < 0;
3527+ vc = v->_mp_size < 0;
3528+ rc = uc ^ vc;
3529+
3530+ ux = -uc;
3531+ vx = -vc;
3532+ rx = -rc;
3533+
3534+ rp = MPZ_REALLOC (r, un + rc);
3535+
3536+ up = u->_mp_d;
3537+ vp = v->_mp_d;
3538+
3539+ i = 0;
3540+ do
3541+ {
3542+ ul = (up[i] ^ ux) + uc;
3543+ uc = ul < uc;
3544+
3545+ vl = (vp[i] ^ vx) + vc;
3546+ vc = vl < vc;
3547+
3548+ rl = (ul ^ vl ^ rx) + rc;
3549+ rc = rl < rc;
3550+ rp[i] = rl;
3551+ }
3552+ while (++i < vn);
3553+ assert (vc == 0);
3554+
3555+ for (; i < un; i++)
3556+ {
3557+ ul = (up[i] ^ ux) + uc;
3558+ uc = ul < uc;
3559+
3560+ rl = (ul ^ ux) + rc;
3561+ rc = rl < rc;
3562+ rp[i] = rl;
3563+ }
3564+ if (rc)
3565+ rp[un++] = rc;
3566+ else
3567+ un = mpn_normalized_size (rp, un);
3568+
3569+ r->_mp_size = rx ? -un : un;
3570+}
3571+
3572+static unsigned
3573+gmp_popcount_limb (mp_limb_t x)
3574+{
3575+ unsigned c;
3576+
3577+ /* Do 16 bits at a time, to avoid limb-sized constants. */
3578+ for (c = 0; x > 0; x >>= 16)
3579+ {
3580+ unsigned w = ((x >> 1) & 0x5555) + (x & 0x5555);
3581+ w = ((w >> 2) & 0x3333) + (w & 0x3333);
3582+ w = ((w >> 4) & 0x0f0f) + (w & 0x0f0f);
3583+ w = (w >> 8) + (w & 0x00ff);
3584+ c += w;
3585+ }
3586+ return c;
3587+}
3588+
3589+mp_bitcnt_t
3590+mpz_popcount (const mpz_t u)
3591+{
3592+ mp_size_t un, i;
3593+ mp_bitcnt_t c;
3594+
3595+ un = u->_mp_size;
3596+
3597+ if (un < 0)
3598+ return ~(mp_bitcnt_t) 0;
3599+
3600+ for (c = 0, i = 0; i < un; i++)
3601+ c += gmp_popcount_limb (u->_mp_d[i]);
3602+
3603+ return c;
3604+}
3605+
3606+mp_bitcnt_t
3607+mpz_hamdist (const mpz_t u, const mpz_t v)
3608+{
3609+ mp_size_t un, vn, i;
3610+ mp_limb_t uc, vc, ul, vl, comp;
3611+ mp_srcptr up, vp;
3612+ mp_bitcnt_t c;
3613+
3614+ un = u->_mp_size;
3615+ vn = v->_mp_size;
3616+
3617+ if ( (un ^ vn) < 0)
3618+ return ~(mp_bitcnt_t) 0;
3619+
3620+ comp = - (uc = vc = (un < 0));
3621+ if (uc)
3622+ {
3623+ assert (vn < 0);
3624+ un = -un;
3625+ vn = -vn;
3626+ }
3627+
3628+ up = u->_mp_d;
3629+ vp = v->_mp_d;
3630+
3631+ if (un < vn)
3632+ MPN_SRCPTR_SWAP (up, un, vp, vn);
3633+
3634+ for (i = 0, c = 0; i < vn; i++)
3635+ {
3636+ ul = (up[i] ^ comp) + uc;
3637+ uc = ul < uc;
3638+
3639+ vl = (vp[i] ^ comp) + vc;
3640+ vc = vl < vc;
3641+
3642+ c += gmp_popcount_limb (ul ^ vl);
3643+ }
3644+ assert (vc == 0);
3645+
3646+ for (; i < un; i++)
3647+ {
3648+ ul = (up[i] ^ comp) + uc;
3649+ uc = ul < uc;
3650+
3651+ c += gmp_popcount_limb (ul ^ comp);
3652+ }
3653+
3654+ return c;
3655+}
3656+
3657+mp_bitcnt_t
3658+mpz_scan1 (const mpz_t u, mp_bitcnt_t starting_bit)
3659+{
3660+ mp_ptr up;
3661+ mp_size_t us, un, i;
3662+ mp_limb_t limb, ux;
3663+
3664+ us = u->_mp_size;
3665+ un = GMP_ABS (us);
3666+ i = starting_bit / GMP_LIMB_BITS;
3667+
3668+ /* Past the end there's no 1 bits for u>=0, or an immediate 1 bit
3669+ for u<0. Notice this test picks up any u==0 too. */
3670+ if (i >= un)
3671+ return (us >= 0 ? ~(mp_bitcnt_t) 0 : starting_bit);
3672+
3673+ up = u->_mp_d;
3674+ ux = 0;
3675+ limb = up[i];
3676+
3677+ if (starting_bit != 0)
3678+ {
3679+ if (us < 0)
3680+ {
3681+ ux = mpn_zero_p (up, i);
3682+ limb = ~ limb + ux;
3683+ ux = - (mp_limb_t) (limb >= ux);
3684+ }
3685+
3686+ /* Mask to 0 all bits before starting_bit, thus ignoring them. */
3687+ limb &= (GMP_LIMB_MAX << (starting_bit % GMP_LIMB_BITS));
3688+ }
3689+
3690+ return mpn_common_scan (limb, i, up, un, ux);
3691+}
3692+
3693+mp_bitcnt_t
3694+mpz_scan0 (const mpz_t u, mp_bitcnt_t starting_bit)
3695+{
3696+ mp_ptr up;
3697+ mp_size_t us, un, i;
3698+ mp_limb_t limb, ux;
3699+
3700+ us = u->_mp_size;
3701+ ux = - (mp_limb_t) (us >= 0);
3702+ un = GMP_ABS (us);
3703+ i = starting_bit / GMP_LIMB_BITS;
3704+
3705+ /* When past end, there's an immediate 0 bit for u>=0, or no 0 bits for
3706+ u<0. Notice this test picks up all cases of u==0 too. */
3707+ if (i >= un)
3708+ return (ux ? starting_bit : ~(mp_bitcnt_t) 0);
3709+
3710+ up = u->_mp_d;
3711+ limb = up[i] ^ ux;
3712+
3713+ if (ux == 0)
3714+ limb -= mpn_zero_p (up, i); /* limb = ~(~limb + zero_p) */
3715+
3716+ /* Mask all bits before starting_bit, thus ignoring them. */
3717+ limb &= (GMP_LIMB_MAX << (starting_bit % GMP_LIMB_BITS));
3718+
3719+ return mpn_common_scan (limb, i, up, un, ux);
3720+}
3721+
3722+
3723+/* MPZ base conversion. */
3724+
3725+size_t
3726+mpz_sizeinbase (const mpz_t u, int base)
3727+{
3728+ mp_size_t un;
3729+ mp_srcptr up;
3730+ mp_ptr tp;
3731+ mp_bitcnt_t bits;
3732+ struct gmp_div_inverse bi;
3733+ size_t ndigits;
3734+
3735+ assert (base >= 2);
3736+ assert (base <= 36);
3737+
3738+ un = GMP_ABS (u->_mp_size);
3739+ if (un == 0)
3740+ return 1;
3741+
3742+ up = u->_mp_d;
3743+
3744+ bits = (un - 1) * GMP_LIMB_BITS + mpn_limb_size_in_base_2 (up[un-1]);
3745+ switch (base)
3746+ {
3747+ case 2:
3748+ return bits;
3749+ case 4:
3750+ return (bits + 1) / 2;
3751+ case 8:
3752+ return (bits + 2) / 3;
3753+ case 16:
3754+ return (bits + 3) / 4;
3755+ case 32:
3756+ return (bits + 4) / 5;
3757+ /* FIXME: Do something more clever for the common case of base
3758+ 10. */
3759+ }
3760+
3761+ tp = gmp_xalloc_limbs (un);
3762+ mpn_copyi (tp, up, un);
3763+ mpn_div_qr_1_invert (&bi, base);
3764+
3765+ ndigits = 0;
3766+ do
3767+ {
3768+ ndigits++;
3769+ mpn_div_qr_1_preinv (tp, tp, un, &bi);
3770+ un -= (tp[un-1] == 0);
3771+ }
3772+ while (un > 0);
3773+
3774+ gmp_free (tp);
3775+ return ndigits;
3776+}
3777+
3778+char *
3779+mpz_get_str (char *sp, int base, const mpz_t u)
3780+{
3781+ unsigned bits;
3782+ const char *digits;
3783+ mp_size_t un;
3784+ size_t i, sn;
3785+
3786+ if (base >= 0)
3787+ {
3788+ digits = "0123456789abcdefghijklmnopqrstuvwxyz";
3789+ }
3790+ else
3791+ {
3792+ base = -base;
3793+ digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
3794+ }
3795+ if (base <= 1)
3796+ base = 10;
3797+ if (base > 36)
3798+ return NULL;
3799+
3800+ sn = 1 + mpz_sizeinbase (u, base);
3801+ if (!sp)
3802+ sp = gmp_xalloc (1 + sn);
3803+
3804+ un = GMP_ABS (u->_mp_size);
3805+
3806+ if (un == 0)
3807+ {
3808+ sp[0] = '0';
3809+ sp[1] = '\0';
3810+ return sp;
3811+ }
3812+
3813+ i = 0;
3814+
3815+ if (u->_mp_size < 0)
3816+ sp[i++] = '-';
3817+
3818+ bits = mpn_base_power_of_two_p (base);
3819+
3820+ if (bits)
3821+ /* Not modified in this case. */
3822+ sn = i + mpn_get_str_bits ((unsigned char *) sp + i, bits, u->_mp_d, un);
3823+ else
3824+ {
3825+ struct mpn_base_info info;
3826+ mp_ptr tp;
3827+
3828+ mpn_get_base_info (&info, base);
3829+ tp = gmp_xalloc_limbs (un);
3830+ mpn_copyi (tp, u->_mp_d, un);
3831+
3832+ sn = i + mpn_get_str_other ((unsigned char *) sp + i, base, &info, tp, un);
3833+ gmp_free (tp);
3834+ }
3835+
3836+ for (; i < sn; i++)
3837+ sp[i] = digits[(unsigned char) sp[i]];
3838+
3839+ sp[sn] = '\0';
3840+ return sp;
3841+}
3842+
3843+int
3844+mpz_set_str (mpz_t r, const char *sp, int base)
3845+{
3846+ unsigned bits;
3847+ mp_size_t rn, alloc;
3848+ mp_ptr rp;
3849+ size_t sn;
3850+ int sign;
3851+ unsigned char *dp;
3852+
3853+ assert (base == 0 || (base >= 2 && base <= 36));
3854+
3855+ while (isspace( (unsigned char) *sp))
3856+ sp++;
3857+
3858+ sign = (*sp == '-');
3859+ sp += sign;
3860+
3861+ if (base == 0)
3862+ {
3863+ if (*sp == '0')
3864+ {
3865+ sp++;
3866+ if (*sp == 'x' || *sp == 'X')
3867+ {
3868+ base = 16;
3869+ sp++;
3870+ }
3871+ else if (*sp == 'b' || *sp == 'B')
3872+ {
3873+ base = 2;
3874+ sp++;
3875+ }
3876+ else
3877+ base = 8;
3878+ }
3879+ else
3880+ base = 10;
3881+ }
3882+
3883+ sn = strlen (sp);
3884+ dp = gmp_xalloc (sn + (sn == 0));
3885+
3886+ for (sn = 0; *sp; sp++)
3887+ {
3888+ unsigned digit;
3889+
3890+ if (isspace ((unsigned char) *sp))
3891+ continue;
3892+ if (*sp >= '0' && *sp <= '9')
3893+ digit = *sp - '0';
3894+ else if (*sp >= 'a' && *sp <= 'z')
3895+ digit = *sp - 'a' + 10;
3896+ else if (*sp >= 'A' && *sp <= 'Z')
3897+ digit = *sp - 'A' + 10;
3898+ else
3899+ digit = base; /* fail */
3900+
3901+ if (digit >= base)
3902+ {
3903+ gmp_free (dp);
3904+ r->_mp_size = 0;
3905+ return -1;
3906+ }
3907+
3908+ dp[sn++] = digit;
3909+ }
3910+
3911+ bits = mpn_base_power_of_two_p (base);
3912+
3913+ if (bits > 0)
3914+ {
3915+ alloc = (sn * bits + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
3916+ rp = MPZ_REALLOC (r, alloc);
3917+ rn = mpn_set_str_bits (rp, dp, sn, bits);
3918+ }
3919+ else
3920+ {
3921+ struct mpn_base_info info;
3922+ mpn_get_base_info (&info, base);
3923+ alloc = (sn + info.exp - 1) / info.exp;
3924+ rp = MPZ_REALLOC (r, alloc);
3925+ rn = mpn_set_str_other (rp, dp, sn, base, &info);
3926+ }
3927+ assert (rn <= alloc);
3928+ gmp_free (dp);
3929+
3930+ r->_mp_size = sign ? - rn : rn;
3931+
3932+ return 0;
3933+}
3934+
3935+int
3936+mpz_init_set_str (mpz_t r, const char *sp, int base)
3937+{
3938+ mpz_init (r);
3939+ return mpz_set_str (r, sp, base);
3940+}
3941+
3942+size_t
3943+mpz_out_str (FILE *stream, int base, const mpz_t x)
3944+{
3945+ char *str;
3946+ size_t len;
3947+
3948+ str = mpz_get_str (NULL, base, x);
3949+ len = strlen (str);
3950+ len = fwrite (str, 1, len, stream);
3951+ gmp_free (str);
3952+ return len;
3953+}
3954+
3955+
3956+static int
3957+gmp_detect_endian (void)
3958+{
3959+ static const int i = 2;
3960+ const unsigned char *p = (const unsigned char *) &i;
3961+ return 1 - *p;
3962+}
3963+
3964+/* Import and export. Does not support nails. */
3965+void
3966+mpz_import (mpz_t r, size_t count, int order, size_t size, int endian,
3967+ size_t nails, const void *src)
3968+{
3969+ const unsigned char *p;
3970+ ptrdiff_t word_step;
3971+ mp_ptr rp;
3972+ mp_size_t rn;
3973+
3974+ /* The current (partial) limb. */
3975+ mp_limb_t limb;
3976+ /* The number of bytes already copied to this limb (starting from
3977+ the low end). */
3978+ size_t bytes;
3979+ /* The index where the limb should be stored, when completed. */
3980+ mp_size_t i;
3981+
3982+ if (nails != 0)
3983+ gmp_die ("mpz_import: Nails not supported.");
3984+
3985+ assert (order == 1 || order == -1);
3986+ assert (endian >= -1 && endian <= 1);
3987+
3988+ if (endian == 0)
3989+ endian = gmp_detect_endian ();
3990+
3991+ p = (unsigned char *) src;
3992+
3993+ word_step = (order != endian) ? 2 * size : 0;
3994+
3995+ /* Process bytes from the least significant end, so point p at the
3996+ least significant word. */
3997+ if (order == 1)
3998+ {
3999+ p += size * (count - 1);
4000+ word_step = - word_step;
4001+ }
4002+
4003+ /* And at least significant byte of that word. */
4004+ if (endian == 1)
4005+ p += (size - 1);
4006+
4007+ rn = (size * count + sizeof(mp_limb_t) - 1) / sizeof(mp_limb_t);
4008+ rp = MPZ_REALLOC (r, rn);
4009+
4010+ for (limb = 0, bytes = 0, i = 0; count > 0; count--, p += word_step)
4011+ {
4012+ size_t j;
4013+ for (j = 0; j < size; j++, p -= (ptrdiff_t) endian)
4014+ {
4015+ limb |= (mp_limb_t) *p << (bytes++ * CHAR_BIT);
4016+ if (bytes == sizeof(mp_limb_t))
4017+ {
4018+ rp[i++] = limb;
4019+ bytes = 0;
4020+ limb = 0;
4021+ }
4022+ }
4023+ }
4024+ assert (i + (bytes > 0) == rn);
4025+ if (limb != 0)
4026+ rp[i++] = limb;
4027+ else
4028+ i = mpn_normalized_size (rp, i);
4029+
4030+ r->_mp_size = i;
4031+}
4032+
4033+void *
4034+mpz_export (void *r, size_t *countp, int order, size_t size, int endian,
4035+ size_t nails, const mpz_t u)
4036+{
4037+ size_t count;
4038+ mp_size_t un;
4039+
4040+ if (nails != 0)
4041+ gmp_die ("mpz_import: Nails not supported.");
4042+
4043+ assert (order == 1 || order == -1);
4044+ assert (endian >= -1 && endian <= 1);
4045+ assert (size > 0 || u->_mp_size == 0);
4046+
4047+ un = u->_mp_size;
4048+ count = 0;
4049+ if (un != 0)
4050+ {
4051+ size_t k;
4052+ unsigned char *p;
4053+ ptrdiff_t word_step;
4054+ /* The current (partial) limb. */
4055+ mp_limb_t limb;
4056+ /* The number of bytes left to to in this limb. */
4057+ size_t bytes;
4058+ /* The index where the limb was read. */
4059+ mp_size_t i;
4060+
4061+ un = GMP_ABS (un);
4062+
4063+ /* Count bytes in top limb. */
4064+ limb = u->_mp_d[un-1];
4065+ assert (limb != 0);
4066+
4067+ k = 0;
4068+ do {
4069+ k++; limb >>= CHAR_BIT;
4070+ } while (limb != 0);
4071+
4072+ count = (k + (un-1) * sizeof (mp_limb_t) + size - 1) / size;
4073+
4074+ if (!r)
4075+ r = gmp_xalloc (count * size);
4076+
4077+ if (endian == 0)
4078+ endian = gmp_detect_endian ();
4079+
4080+ p = (unsigned char *) r;
4081+
4082+ word_step = (order != endian) ? 2 * size : 0;
4083+
4084+ /* Process bytes from the least significant end, so point p at the
4085+ least significant word. */
4086+ if (order == 1)
4087+ {
4088+ p += size * (count - 1);
4089+ word_step = - word_step;
4090+ }
4091+
4092+ /* And at least significant byte of that word. */
4093+ if (endian == 1)
4094+ p += (size - 1);
4095+
4096+ for (bytes = 0, i = 0, k = 0; k < count; k++, p += word_step)
4097+ {
4098+ size_t j;
4099+ for (j = 0; j < size; j++, p -= (ptrdiff_t) endian)
4100+ {
4101+ if (bytes == 0)
4102+ {
4103+ if (i < un)
4104+ limb = u->_mp_d[i++];
4105+ bytes = sizeof (mp_limb_t);
4106+ }
4107+ *p = limb;
4108+ limb >>= CHAR_BIT;
4109+ bytes--;
4110+ }
4111+ }
4112+ assert (i == un);
4113+ assert (k == count);
4114+ }
4115+
4116+ if (countp)
4117+ *countp = count;
4118+
4119+ return r;
4120+}
rts/mini-gmp.hnew file+259
@@ -0,0 +1,259 @@
1+/* mini-gmp, a minimalistic implementation of a GNU GMP subset.
2+
3+Copyright 2011, 2012, 2013 Free Software Foundation, Inc.
4+
5+This file is part of the GNU MP Library.
6+
7+The GNU MP Library is free software; you can redistribute it and/or modify
8+it under the terms of the GNU Lesser General Public License as published by
9+the Free Software Foundation; either version 3 of the License, or (at your
10+option) any later version.
11+
12+The GNU MP Library is distributed in the hope that it will be useful, but
13+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15+License for more details.
16+
17+You should have received a copy of the GNU Lesser General Public License
18+along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
19+
20+/* About mini-gmp: This is a minimal implementation of a subset of the
21+ GMP interface. It is intended for inclusion into applications which
22+ have modest bignums needs, as a fallback when the real GMP library
23+ is not installed.
24+
25+ This file defines the public interface. */
26+
27+#ifndef __MINI_GMP_H__
28+#define __MINI_GMP_H__
29+
30+/* For size_t */
31+#include <stddef.h>
32+
33+#if defined (__cplusplus)
34+extern "C" {
35+#endif
36+
37+void mp_set_memory_functions (void *(*) (size_t),
38+ void *(*) (void *, size_t, size_t),
39+ void (*) (void *, size_t));
40+
41+void mp_get_memory_functions (void *(**) (size_t),
42+ void *(**) (void *, size_t, size_t),
43+ void (**) (void *, size_t));
44+
45+typedef unsigned long mp_limb_t;
46+typedef long mp_size_t;
47+typedef unsigned long mp_bitcnt_t;
48+
49+typedef mp_limb_t *mp_ptr;
50+typedef const mp_limb_t *mp_srcptr;
51+
52+typedef struct
53+{
54+ int _mp_alloc; /* Number of *limbs* allocated and pointed
55+ to by the _mp_d field. */
56+ int _mp_size; /* abs(_mp_size) is the number of limbs the
57+ last field points to. If _mp_size is
58+ negative this is a negative number. */
59+ mp_limb_t *_mp_d; /* Pointer to the limbs. */
60+} __mpz_struct;
61+
62+typedef __mpz_struct mpz_t[1];
63+
64+typedef __mpz_struct *mpz_ptr;
65+typedef const __mpz_struct *mpz_srcptr;
66+
67+void mpn_copyi (mp_ptr, mp_srcptr, mp_size_t);
68+void mpn_copyd (mp_ptr, mp_srcptr, mp_size_t);
69+
70+int mpn_cmp (mp_srcptr, mp_srcptr, mp_size_t);
71+
72+mp_limb_t mpn_add_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
73+mp_limb_t mpn_add_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
74+mp_limb_t mpn_add (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
75+
76+mp_limb_t mpn_sub_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
77+mp_limb_t mpn_sub_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
78+mp_limb_t mpn_sub (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
79+
80+mp_limb_t mpn_mul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
81+mp_limb_t mpn_addmul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
82+mp_limb_t mpn_submul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
83+
84+mp_limb_t mpn_mul (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
85+void mpn_mul_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
86+void mpn_sqr (mp_ptr, mp_srcptr, mp_size_t);
87+
88+mp_limb_t mpn_lshift (mp_ptr, mp_srcptr, mp_size_t, unsigned int);
89+mp_limb_t mpn_rshift (mp_ptr, mp_srcptr, mp_size_t, unsigned int);
90+
91+mp_bitcnt_t mpn_scan0 (mp_srcptr, mp_bitcnt_t);
92+mp_bitcnt_t mpn_scan1 (mp_srcptr, mp_bitcnt_t);
93+
94+mp_limb_t mpn_invert_3by2 (mp_limb_t, mp_limb_t);
95+#define mpn_invert_limb(x) mpn_invert_3by2 ((x), 0)
96+
97+size_t mpn_get_str (unsigned char *, int, mp_ptr, mp_size_t);
98+mp_size_t mpn_set_str (mp_ptr, const unsigned char *, size_t, int);
99+
100+void mpz_init (mpz_t);
101+void mpz_init2 (mpz_t, mp_bitcnt_t);
102+void mpz_clear (mpz_t);
103+
104+#define mpz_odd_p(z) (((z)->_mp_size != 0) & (int) (z)->_mp_d[0])
105+#define mpz_even_p(z) (! mpz_odd_p (z))
106+
107+int mpz_sgn (const mpz_t);
108+int mpz_cmp_si (const mpz_t, long);
109+int mpz_cmp_ui (const mpz_t, unsigned long);
110+int mpz_cmp (const mpz_t, const mpz_t);
111+int mpz_cmpabs_ui (const mpz_t, unsigned long);
112+int mpz_cmpabs (const mpz_t, const mpz_t);
113+int mpz_cmp_d (const mpz_t, double);
114+int mpz_cmpabs_d (const mpz_t, double);
115+
116+void mpz_abs (mpz_t, const mpz_t);
117+void mpz_neg (mpz_t, const mpz_t);
118+void mpz_swap (mpz_t, mpz_t);
119+
120+void mpz_add_ui (mpz_t, const mpz_t, unsigned long);
121+void mpz_add (mpz_t, const mpz_t, const mpz_t);
122+void mpz_sub_ui (mpz_t, const mpz_t, unsigned long);
123+void mpz_ui_sub (mpz_t, unsigned long, const mpz_t);
124+void mpz_sub (mpz_t, const mpz_t, const mpz_t);
125+
126+void mpz_mul_si (mpz_t, const mpz_t, long int);
127+void mpz_mul_ui (mpz_t, const mpz_t, unsigned long int);
128+void mpz_mul (mpz_t, const mpz_t, const mpz_t);
129+void mpz_mul_2exp (mpz_t, const mpz_t, mp_bitcnt_t);
130+
131+void mpz_cdiv_qr (mpz_t, mpz_t, const mpz_t, const mpz_t);
132+void mpz_fdiv_qr (mpz_t, mpz_t, const mpz_t, const mpz_t);
133+void mpz_tdiv_qr (mpz_t, mpz_t, const mpz_t, const mpz_t);
134+void mpz_cdiv_q (mpz_t, const mpz_t, const mpz_t);
135+void mpz_fdiv_q (mpz_t, const mpz_t, const mpz_t);
136+void mpz_tdiv_q (mpz_t, const mpz_t, const mpz_t);
137+void mpz_cdiv_r (mpz_t, const mpz_t, const mpz_t);
138+void mpz_fdiv_r (mpz_t, const mpz_t, const mpz_t);
139+void mpz_tdiv_r (mpz_t, const mpz_t, const mpz_t);
140+
141+void mpz_cdiv_q_2exp (mpz_t, const mpz_t, mp_bitcnt_t);
142+void mpz_fdiv_q_2exp (mpz_t, const mpz_t, mp_bitcnt_t);
143+void mpz_tdiv_q_2exp (mpz_t, const mpz_t, mp_bitcnt_t);
144+void mpz_cdiv_r_2exp (mpz_t, const mpz_t, mp_bitcnt_t);
145+void mpz_fdiv_r_2exp (mpz_t, const mpz_t, mp_bitcnt_t);
146+void mpz_tdiv_r_2exp (mpz_t, const mpz_t, mp_bitcnt_t);
147+
148+void mpz_mod (mpz_t, const mpz_t, const mpz_t);
149+
150+void mpz_divexact (mpz_t, const mpz_t, const mpz_t);
151+
152+int mpz_divisible_p (const mpz_t, const mpz_t);
153+
154+unsigned long mpz_cdiv_qr_ui (mpz_t, mpz_t, const mpz_t, unsigned long);
155+unsigned long mpz_fdiv_qr_ui (mpz_t, mpz_t, const mpz_t, unsigned long);
156+unsigned long mpz_tdiv_qr_ui (mpz_t, mpz_t, const mpz_t, unsigned long);
157+unsigned long mpz_cdiv_q_ui (mpz_t, const mpz_t, unsigned long);
158+unsigned long mpz_fdiv_q_ui (mpz_t, const mpz_t, unsigned long);
159+unsigned long mpz_tdiv_q_ui (mpz_t, const mpz_t, unsigned long);
160+unsigned long mpz_cdiv_r_ui (mpz_t, const mpz_t, unsigned long);
161+unsigned long mpz_fdiv_r_ui (mpz_t, const mpz_t, unsigned long);
162+unsigned long mpz_tdiv_r_ui (mpz_t, const mpz_t, unsigned long);
163+unsigned long mpz_cdiv_ui (const mpz_t, unsigned long);
164+unsigned long mpz_fdiv_ui (const mpz_t, unsigned long);
165+unsigned long mpz_tdiv_ui (const mpz_t, unsigned long);
166+
167+unsigned long mpz_mod_ui (mpz_t, const mpz_t, unsigned long);
168+
169+void mpz_divexact_ui (mpz_t, const mpz_t, unsigned long);
170+
171+int mpz_divisible_ui_p (const mpz_t, unsigned long);
172+
173+unsigned long mpz_gcd_ui (mpz_t, const mpz_t, unsigned long);
174+void mpz_gcd (mpz_t, const mpz_t, const mpz_t);
175+void mpz_gcdext (mpz_t, mpz_t, mpz_t, const mpz_t, const mpz_t);
176+void mpz_lcm_ui (mpz_t, const mpz_t, unsigned long);
177+void mpz_lcm (mpz_t, const mpz_t, const mpz_t);
178+int mpz_invert (mpz_t, const mpz_t, const mpz_t);
179+
180+void mpz_sqrtrem (mpz_t, mpz_t, const mpz_t);
181+void mpz_sqrt (mpz_t, const mpz_t);
182+
183+void mpz_pow_ui (mpz_t, const mpz_t, unsigned long);
184+void mpz_ui_pow_ui (mpz_t, unsigned long, unsigned long);
185+void mpz_powm (mpz_t, const mpz_t, const mpz_t, const mpz_t);
186+void mpz_powm_ui (mpz_t, const mpz_t, unsigned long, const mpz_t);
187+
188+void mpz_rootrem (mpz_t, mpz_t, const mpz_t, unsigned long);
189+int mpz_root (mpz_t, const mpz_t, unsigned long);
190+
191+void mpz_fac_ui (mpz_t, unsigned long);
192+void mpz_bin_uiui (mpz_t, unsigned long, unsigned long);
193+
194+int mpz_tstbit (const mpz_t, mp_bitcnt_t);
195+void mpz_setbit (mpz_t, mp_bitcnt_t);
196+void mpz_clrbit (mpz_t, mp_bitcnt_t);
197+void mpz_combit (mpz_t, mp_bitcnt_t);
198+
199+void mpz_com (mpz_t, const mpz_t);
200+void mpz_and (mpz_t, const mpz_t, const mpz_t);
201+void mpz_ior (mpz_t, const mpz_t, const mpz_t);
202+void mpz_xor (mpz_t, const mpz_t, const mpz_t);
203+
204+mp_bitcnt_t mpz_popcount (const mpz_t);
205+mp_bitcnt_t mpz_hamdist (const mpz_t, const mpz_t);
206+mp_bitcnt_t mpz_scan0 (const mpz_t, mp_bitcnt_t);
207+mp_bitcnt_t mpz_scan1 (const mpz_t, mp_bitcnt_t);
208+
209+int mpz_fits_slong_p (const mpz_t);
210+int mpz_fits_ulong_p (const mpz_t);
211+long int mpz_get_si (const mpz_t);
212+unsigned long int mpz_get_ui (const mpz_t);
213+double mpz_get_d (const mpz_t);
214+size_t mpz_size (const mpz_t);
215+mp_limb_t mpz_getlimbn (const mpz_t, mp_size_t);
216+
217+void mpz_set_si (mpz_t, signed long int);
218+void mpz_set_ui (mpz_t, unsigned long int);
219+void mpz_set (mpz_t, const mpz_t);
220+void mpz_set_d (mpz_t, double);
221+
222+void mpz_init_set_si (mpz_t, signed long int);
223+void mpz_init_set_ui (mpz_t, unsigned long int);
224+void mpz_init_set (mpz_t, const mpz_t);
225+void mpz_init_set_d (mpz_t, double);
226+
227+size_t mpz_sizeinbase (const mpz_t, int);
228+char *mpz_get_str (char *, int, const mpz_t);
229+int mpz_set_str (mpz_t, const char *, int);
230+int mpz_init_set_str (mpz_t, const char *, int);
231+
232+/* This long list taken from gmp.h. */
233+/* For reference, "defined(EOF)" cannot be used here. In g++ 2.95.4,
234+ <iostream> defines EOF but not FILE. */
235+#if defined (FILE) \
236+ || defined (H_STDIO) \
237+ || defined (_H_STDIO) /* AIX */ \
238+ || defined (_STDIO_H) /* glibc, Sun, SCO */ \
239+ || defined (_STDIO_H_) /* BSD, OSF */ \
240+ || defined (__STDIO_H) /* Borland */ \
241+ || defined (__STDIO_H__) /* IRIX */ \
242+ || defined (_STDIO_INCLUDED) /* HPUX */ \
243+ || defined (__dj_include_stdio_h_) /* DJGPP */ \
244+ || defined (_FILE_DEFINED) /* Microsoft */ \
245+ || defined (__STDIO__) /* Apple MPW MrC */ \
246+ || defined (_MSL_STDIO_H) /* Metrowerks */ \
247+ || defined (_STDIO_H_INCLUDED) /* QNX4 */ \
248+ || defined (_ISO_STDIO_ISO_H) /* Sun C++ */ \
249+ || defined (__STDIO_LOADED) /* VMS */
250+size_t mpz_out_str (FILE *, int, const mpz_t);
251+#endif
252+
253+void mpz_import (mpz_t, size_t, int, size_t, int, size_t, const void *);
254+void *mpz_export (void *, size_t *, int, size_t, int, size_t, const mpz_t);
255+
256+#if defined (__cplusplus)
257+}
258+#endif
259+#endif /* __MINI_GMP_H__ */
src/IRTS/CodegenC.hs+1−1
@@ -201,7 +201,7 @@ bcc i (CONSTCASE r code def)
201 indent i ++ "if (GETINT(" ++ v ++ ") == " ++ show b ++ ") {\n"
201 indent i ++ "if (GETINT(" ++ v ++ ") == " ++ show b ++ ") {\n"
202 ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
202 ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
203 iCase v (Ch b, bc) =
203 iCase v (Ch b, bc) =
204− indent i ++ "if (GETINT(" ++ v ++ ") == " ++ show b ++ ") {\n"
204+ indent i ++ "if (GETINT(" ++ v ++ ") == " ++ show (fromEnum b) ++ ") {\n"
205 ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
205 ++ concatMap (bcc (i+1)) bc ++ indent i ++ "} else\n"
206
206
207 showCase i (t, bc) = indent i ++ "case " ++ show t ++ ":\n"
207 showCase i (t, bc) = indent i ++ "case " ++ show t ++ ":\n"
src/IRTS/Compiler.hs−8
@@ -110,14 +110,6 @@ irMain :: TT Name -> Idris LDecl
110irMain tm = do i <- ir tm
110irMain tm = do i <- ir tm
111 return $ LFun [] (MN 0 "runMain") [] (LForce i)
111 return $ LFun [] (MN 0 "runMain") [] (LForce i)
112
112
113−allNames :: [Name] -> Name -> Idris [Name]
114−allNames ns n | n `elem` ns = return []
115−allNames ns n = do i <- getIState
116− case lookupCtxtExact n (idris_callgraph i) of
117− [ns'] -> do more <- mapM (allNames (n:ns)) (map fst (calls ns'))
118− return (nub (n : concat more))
119− _ -> return [n]
120−
121mkDecls :: Term -> [Name] -> Idris [(Name, LDecl)]
113mkDecls :: Term -> [Name] -> Idris [(Name, LDecl)]
122mkDecls t used
114mkDecls t used
123 = do i <- getIState
115 = do i <- getIState
src/IRTS/Java/JTypes.hs+1
@@ -218,6 +218,7 @@ opName x
218 | (LTrunc _ to) <- x = "LTrunc" ++ (suffixFor to)
218 | (LTrunc _ to) <- x = "LTrunc" ++ (suffixFor to)
219 | (LFloatInt to) <- x = "LFloatInt" ++ (suffixFor to)
219 | (LFloatInt to) <- x = "LFloatInt" ++ (suffixFor to)
220 | (LStrInt to) <- x = "LStrInt" ++ (suffixFor to)
220 | (LStrInt to) <- x = "LStrInt" ++ (suffixFor to)
221+ | (LChInt to) <- x = "LChInt" ++ (suffixFor to)
221 | otherwise = takeWhile ((/=) ' ') $ show x
222 | otherwise = takeWhile ((/=) ' ') $ show x
222 where
223 where
223 suffixFor (ITFixed nt) = show nt
224 suffixFor (ITFixed nt) = show nt
src/Idris/AbsSyntax.hs+33−3
@@ -96,6 +96,11 @@ addTrans t = do i <- getIState
96totcheck :: (FC, Name) -> Idris ()
96totcheck :: (FC, Name) -> Idris ()
97totcheck n = do i <- getIState; putIState $ i { idris_totcheck = idris_totcheck i ++ [n] }
97totcheck n = do i <- getIState; putIState $ i { idris_totcheck = idris_totcheck i ++ [n] }
98
98
99+defer_totcheck :: (FC, Name) -> Idris ()
100+defer_totcheck n
101+ = do i <- getIState;
102+ putIState $ i { idris_defertotcheck = nub (idris_defertotcheck i ++ [n]) }
103+
99clear_totcheck :: Idris ()
104clear_totcheck :: Idris ()
100clear_totcheck = do i <- getIState; putIState $ i { idris_totcheck = [] }
105clear_totcheck = do i <- getIState; putIState $ i { idris_totcheck = [] }
101
106
@@ -141,6 +146,18 @@ addToCG n cg
141 = do i <- getIState
146 = do i <- getIState
142 putIState $ i { idris_callgraph = addDef n cg (idris_callgraph i) }
147 putIState $ i { idris_callgraph = addDef n cg (idris_callgraph i) }
143
148
149+-- Trace all the names in a call graph starting at the given name
150+getAllNames :: Name -> Idris [Name]
151+getAllNames n = allNames [] n
152+
153+allNames :: [Name] -> Name -> Idris [Name]
154+allNames ns n | n `elem` ns = return []
155+allNames ns n = do i <- getIState
156+ case lookupCtxtExact n (idris_callgraph i) of
157+ [ns'] -> do more <- mapM (allNames (n:ns)) (map fst (calls ns'))
158+ return (nub (n : concat more))
159+ _ -> return [n]
160+
144addCoercion :: Name -> Idris ()
161addCoercion :: Name -> Idris ()
145addCoercion n = do i <- getIState
162addCoercion n = do i <- getIState
146 putIState $ i { idris_coercions = nub $ n : idris_coercions i }
163 putIState $ i { idris_coercions = nub $ n : idris_coercions i }
@@ -409,6 +426,17 @@ setREPL t = do i <- getIState
409 let opt' = opts { opt_repl = t }
426 let opt' = opts { opt_repl = t }
410 putIState $ i { idris_options = opt' }
427 putIState $ i { idris_options = opt' }
411
428
429+setNoBanner :: Bool -> Idris ()
430+setNoBanner n = do i <- getIState
431+ let opts = idris_options i
432+ let opt' = opts {opt_nobanner = n}
433+ putIState $ i { idris_options = opt' }
434+
435+getNoBanner :: Idris Bool
436+getNoBanner = do i <- getIState
437+ let opts = idris_options i
438+ return (opt_nobanner opts)
439+
412setQuiet :: Bool -> Idris ()
440setQuiet :: Bool -> Idris ()
413setQuiet q = do i <- getIState
441setQuiet q = do i <- getIState
414 let opts = idris_options i
442 let opts = idris_options i
@@ -879,15 +907,15 @@ addStatics n tm ptm =
879 do let (statics, dynamics) = initStatics tm ptm
907 do let (statics, dynamics) = initStatics tm ptm
880 let stnames = nub $ concatMap freeArgNames (map snd statics)
908 let stnames = nub $ concatMap freeArgNames (map snd statics)
881 let dnames = nub $ concatMap freeArgNames (map snd dynamics)
909 let dnames = nub $ concatMap freeArgNames (map snd dynamics)
882− when (not (null statics)) $
883− logLvl 7 $ show n ++ " " ++ show statics ++ "\n" ++ show dynamics
884− ++ "\n" ++ show stnames ++ "\n" ++ show dnames
885 -- also get the arguments which are 'uniquely inferrable' from
910 -- also get the arguments which are 'uniquely inferrable' from
886 -- statics (see sec 4.2 of "Scrapping Your Inefficient Engine")
911 -- statics (see sec 4.2 of "Scrapping Your Inefficient Engine")
887 let statics' = nub $ map fst statics ++
912 let statics' = nub $ map fst statics ++
888 filter (\x -> not (elem x dnames)) stnames
913 filter (\x -> not (elem x dnames)) stnames
889 let stpos = staticList statics' tm
914 let stpos = staticList statics' tm
890 i <- getIState
915 i <- getIState
916+ when (not (null statics)) $
917+ logLvl 5 $ show n ++ " " ++ show statics' ++ "\n" ++ show dynamics
918+ ++ "\n" ++ show stnames ++ "\n" ++ show dnames
891 putIState $ i { idris_statics = addDef n stpos (idris_statics i) }
919 putIState $ i { idris_statics = addDef n stpos (idris_statics i) }
892 addIBC (IBCStatic n)
920 addIBC (IBCStatic n)
893 where
921 where
@@ -899,6 +927,8 @@ addStatics n tm ptm =
899 else (static, dynamic)
927 else (static, dynamic)
900 initStatics t pt = ([], [])
928 initStatics t pt = ([], [])
901
929
930+ freeArgNames (Bind n (Pi ty) sc)
931+ = nub $ freeArgNames ty
902 freeArgNames tm = let (_, args) = unApply tm in
932 freeArgNames tm = let (_, args) = unApply tm in
903 concatMap freeNames args
933 concatMap freeNames args
904
934
src/Idris/AbsSyntaxTree.hs+6−2
@@ -37,6 +37,7 @@ data IOption = IOption { opt_logLevel :: Int,
37 opt_errContext :: Bool,
37 opt_errContext :: Bool,
38 opt_repl :: Bool,
38 opt_repl :: Bool,
39 opt_verbose :: Bool,
39 opt_verbose :: Bool,
40+ opt_nobanner :: Bool,
40 opt_quiet :: Bool,
41 opt_quiet :: Bool,
41 opt_codegen :: Codegen,
42 opt_codegen :: Codegen,
42 opt_outputTy :: OutputType,
43 opt_outputTy :: OutputType,
@@ -57,6 +58,7 @@ defaultOpts = IOption { opt_logLevel = 0
57 , opt_errContext = False
58 , opt_errContext = False
58 , opt_repl = True
59 , opt_repl = True
59 , opt_verbose = True
60 , opt_verbose = True
61+ , opt_nobanner = False
60 , opt_quiet = False
62 , opt_quiet = False
61 , opt_codegen = ViaC
63 , opt_codegen = ViaC
62 , opt_outputTy = Executable
64 , opt_outputTy = Executable
@@ -96,7 +98,8 @@ data IState = IState {
96 idris_callgraph :: Ctxt CGInfo, -- name, args used in each pos
98 idris_callgraph :: Ctxt CGInfo, -- name, args used in each pos
97 idris_calledgraph :: Ctxt [Name],
99 idris_calledgraph :: Ctxt [Name],
98 idris_docstrings :: Ctxt String,
100 idris_docstrings :: Ctxt String,
99− idris_totcheck :: [(FC, Name)],
101+ idris_totcheck :: [(FC, Name)], -- names to check totality on
102+ idris_defertotcheck :: [(FC, Name)], -- names to check at the end
100 idris_options :: IOption,
103 idris_options :: IOption,
101 idris_name :: Int,
104 idris_name :: Int,
102 idris_lineapps :: [((FilePath, Int), PTerm)],
105 idris_lineapps :: [((FilePath, Int), PTerm)],
@@ -186,7 +189,7 @@ data IBCWrite = IBCFix FixDecl
186idrisInit = IState initContext [] [] emptyContext emptyContext emptyContext
189idrisInit = IState initContext [] [] emptyContext emptyContext emptyContext
187 emptyContext emptyContext emptyContext emptyContext
190 emptyContext emptyContext emptyContext emptyContext
188 emptyContext emptyContext emptyContext emptyContext
191 emptyContext emptyContext emptyContext emptyContext
189− [] defaultOpts 6 [] [] [] [] [] [] [] [] [] [] [] []
192+ [] [] defaultOpts 6 [] [] [] [] [] [] [] [] [] [] [] []
190 [] Nothing Nothing [] [] [] Hidden False [] Nothing [] [] RawOutput
193 [] Nothing Nothing [] [] [] Hidden False [] Nothing [] [] RawOutput
191 True defaultTheme stdout
194 True defaultTheme stdout
192
195
@@ -256,6 +259,7 @@ data Opt = Filename String
256 | Ver
259 | Ver
257 | Usage
260 | Usage
258 | Quiet
261 | Quiet
262+ | NoBanner
259 | ColourREPL Bool
263 | ColourREPL Bool
260 | Ideslave
264 | Ideslave
261 | ShowLibs
265 | ShowLibs
src/Idris/CaseSplit.hs+4−1
@@ -303,5 +303,8 @@ mkWith str n = let ind = getIndent str
303
303
304 replaceRHS [] str = str
304 replaceRHS [] str = str
305 replaceRHS ('?':'=': rest) str = str
305 replaceRHS ('?':'=': rest) str = str
306− replaceRHS ('=': rest) str = str
306+ replaceRHS ('=': rest) str
307+ | not ('=' `elem` rest) = str
307 replaceRHS (x : rest) str = x : replaceRHS rest str
308 replaceRHS (x : rest) str = x : replaceRHS rest str
309+
310+
src/Idris/Core/Evaluate.hs+5−3
@@ -151,7 +151,7 @@ usable True n ns
151 case lookup n ls of
151 case lookup n ls of
152 Just 0 -> return (False, ns)
152 Just 0 -> return (False, ns)
153 Just i -> return (True, ns)
153 Just i -> return (True, ns)
154− _ -> return (True, ns)
154+ _ -> return (False, ns)
155usable False n ns
155usable False n ns
156 = case lookup n ns of
156 = case lookup n ns of
157 Just 0 -> return (False, ns)
157 Just 0 -> return (False, ns)
@@ -207,10 +207,12 @@ eval traceon ctxt ntimes genv tm opts = ev ntimes [] True [] tm where
207 case val of
207 case val of
208 [(Function _ tm, Public)] ->
208 [(Function _ tm, Public)] ->
209 ev ntimes (n:stk) True env tm
209 ev ntimes (n:stk) True env tm
210+ [(Function _ tm, Hidden)] ->
211+ ev ntimes (n:stk) True env tm
210 [(TyDecl nt ty, _)] -> do vty <- ev ntimes stk True env ty
212 [(TyDecl nt ty, _)] -> do vty <- ev ntimes stk True env ty
211 return $ VP nt n vty
213 return $ VP nt n vty
212 [(CaseOp ci _ _ _ cd, acc)]
214 [(CaseOp ci _ _ _ cd, acc)]
213− | acc == Public &&
215+ | (acc /= Frozen) &&
214 null (fst (cases_totcheck cd)) -> -- unoptimised version
216 null (fst (cases_totcheck cd)) -> -- unoptimised version
215 let (ns, tree) = getCases cd in
217 let (ns, tree) = getCases cd in
216 if blockSimplify ci n stk
218 if blockSimplify ci n stk
@@ -308,7 +310,7 @@ eval traceon ctxt ntimes genv tm opts = ev ntimes [] True [] tm where
308 do let val = lookupDefAcc n (spec || atRepl) ctxt
310 do let val = lookupDefAcc n (spec || atRepl) ctxt
309 case val of
311 case val of
310 [(CaseOp ci _ _ _ cd, acc)]
312 [(CaseOp ci _ _ _ cd, acc)]
311− | acc == Public -> -- unoptimised version
313+ | acc /= Frozen -> -- unoptimised version
312 let (ns, tree) = getCases cd in
314 let (ns, tree) = getCases cd in
313 if blockSimplify ci n stk
315 if blockSimplify ci n stk
314 then return $ unload env (VP Ref n ty) args
316 then return $ unload env (VP Ref n ty) args
src/Idris/Coverage.hs+42−19
@@ -50,7 +50,7 @@ genClauses fc n xs given
50 logLvl 5 $ show (map length argss) ++ "\n" ++ show (map length all_args)
50 logLvl 5 $ show (map length argss) ++ "\n" ++ show (map length all_args)
51 logLvl 10 $ show argss ++ "\n" ++ show all_args
51 logLvl 10 $ show argss ++ "\n" ++ show all_args
52 logLvl 10 $ "Original: \n" ++
52 logLvl 10 $ "Original: \n" ++
53− showSep "\n" (map (\t -> showImp Nothing True False (delab' i t True)) xs)
53+ showSep "\n" (map (\t -> showImp Nothing True False (delab' i t True True)) xs)
54 -- add an infinite supply of explicit arguments to update the possible
54 -- add an infinite supply of explicit arguments to update the possible
55 -- cases for (the return type may be variadic, or function type, sp
55 -- cases for (the return type may be variadic, or function type, sp
56 -- there may be more case splitting that the idris_implicits record
56 -- there may be more case splitting that the idris_implicits record
@@ -68,13 +68,13 @@ genClauses fc n xs given
68 return new
68 return new
69-- return (map (\t -> PClause n t [] PImpossible []) new)
69-- return (map (\t -> PClause n t [] PImpossible []) new)
70 where getLHS i term
70 where getLHS i term
71− | (f, args) <- unApply term = map (\t -> delab' i t True) args
71+ | (f, args) <- unApply term = map (\t -> delab' i t True True) args
72 | otherwise = []
72 | otherwise = []
73
73
74 lhsApp (PClause _ _ l _ _ _) = l
74 lhsApp (PClause _ _ l _ _ _) = l
75 lhsApp (PWith _ _ l _ _ _) = l
75 lhsApp (PWith _ _ l _ _ _) = l
76
76
77− noMatch i tm = all (\x -> case matchClause i (delab' i x True) tm of
77+ noMatch i tm = all (\x -> case matchClause i (delab' i x True True) tm of
78 Right _ -> False
78 Right _ -> False
79 Left miss -> True) xs
79 Left miss -> True) xs
80
80
@@ -423,7 +423,15 @@ buildSCG' ist pats args = nub $ concatMap scgPat pats where
423 | not (f `elem` pvs) = [(f, [])]
423 | not (f `elem` pvs) = [(f, [])]
424 findCalls _ _ _ = []
424 findCalls _ _ _ = []
425
425
426+ expandToArity n args
427+ = case lookupTy n (tt_ctxt ist) of
428+ [ty] -> expand 0 (normalise (tt_ctxt ist) [] ty) args
429+ _ -> args
430+ where expand i (Bind n (Pi _) sc) (x : xs) = x : expand (i + 1) sc xs
431+ expand i (Bind n (Pi _) sc) [] = Just (i, Same) : expand (i + 1) sc []
432+ expand i _ xs = xs
433+
426− mkChange n args pargs = [(n, sizes args)]
434+ mkChange n args pargs = [(n, expandToArity n (sizes args))]
427 where
435 where
428 sizes [] = []
436 sizes [] = []
429 sizes (a : as) = checkSize a pargs 0 : sizes as
437 sizes (a : as) = checkSize a pargs 0 : sizes as
@@ -574,12 +582,16 @@ checkSizeChange n = do
574 -- thread, then the function terminates
582 -- thread, then the function terminates
575 -- also need to checks functions called are all total
583 -- also need to checks functions called are all total
576 -- (Unchecked is okay as we'll spot problems here)
584 -- (Unchecked is okay as we'll spot problems here)
577− let tot = map (checkMP ist (length (argsdef cg))) ms
585+ let tot = map (checkMP ist (getArity ist n)) ms
578 logLvl 4 $ "Generated " ++ show (length tot) ++ " paths"
586 logLvl 4 $ "Generated " ++ show (length tot) ++ " paths"
579 logLvl 6 $ "Paths for " ++ show n ++ " yield " ++ (show tot)
587 logLvl 6 $ "Paths for " ++ show n ++ " yield " ++ (show tot)
580 return (noPartial tot)
588 return (noPartial tot)
581 [] -> do logLvl 5 $ "No paths for " ++ show n
589 [] -> do logLvl 5 $ "No paths for " ++ show n
582 return Unchecked
590 return Unchecked
591+ where getArity ist n
592+ = case lookupTy n (tt_ctxt ist) of
593+ [ty] -> arity (normalise (tt_ctxt ist) [] ty)
594+ _ -> error "Can't happen: checkSizeChange.getArity"
583
595
584type MultiPath = [SCGEntry]
596type MultiPath = [SCGEntry]
585
597
@@ -609,19 +621,21 @@ mkMultiPaths ist path cg
609
621
610checkMP :: IState -> Int -> MultiPath -> Totality
622checkMP :: IState -> Int -> MultiPath -> Totality
611checkMP ist i mp = if i > 0
623checkMP ist i mp = if i > 0
612− then collapse (map (tryPath 0 [] mp) [0..i-1])
624+ then let paths = (map (tryPath 0 [] mp) [0..i-1]) in
625+-- trace ("Paths " ++ show paths) $
626+ collapse paths
613 else tryPath 0 [] mp 0
627 else tryPath 0 [] mp 0
614 where
628 where
615 tryPath' d path mp arg
629 tryPath' d path mp arg
616 = let res = tryPath d path mp arg in
630 = let res = tryPath d path mp arg in
617 trace (show mp ++ "\n" ++ show arg ++ " " ++ show res) res
631 trace (show mp ++ "\n" ++ show arg ++ " " ++ show res) res
618
632
619− tryPath :: Int -> [(SCGEntry, Int)] -> MultiPath -> Int -> Totality
633+ tryPath :: Int -> [((SCGEntry, Int), Int)] -> MultiPath -> Int -> Totality
620 tryPath desc path [] _ = Total []
634 tryPath desc path [] _ = Total []
621-- tryPath desc path ((UN "believe_me", _) : _) arg
635-- tryPath desc path ((UN "believe_me", _) : _) arg
622-- = Partial BelieveMe
636-- = Partial BelieveMe
623 -- if we get to a constructor, it's fine as long as it's strictly positive
637 -- if we get to a constructor, it's fine as long as it's strictly positive
624− tryPath desc path ((f, _) :es) arg
638+ tryPath desc path ((f, _) : es) arg
625 | [TyDecl (DCon _ _) _] <- lookupDef f (tt_ctxt ist)
639 | [TyDecl (DCon _ _) _] <- lookupDef f (tt_ctxt ist)
626 = case lookupTotal f (tt_ctxt ist) of
640 = case lookupTotal f (tt_ctxt ist) of
627 [Total _] -> Unchecked -- okay so far
641 [Total _] -> Unchecked -- okay so far
@@ -632,37 +646,46 @@ checkMP ist i mp = if i > 0
632 tryPath desc path (e@(f, args) : es) arg
646 tryPath desc path (e@(f, args) : es) arg
633 | e `elem` es && allNothing args = Partial (Mutual [f])
647 | e `elem` es && allNothing args = Partial (Mutual [f])
634 tryPath desc path (e@(f, nextargs) : es) arg
648 tryPath desc path (e@(f, nextargs) : es) arg
635− | Just d <- lookup e path
649+ | Just d <- lookup (e, arg) path
636 = if desc > 0
650 = if desc > 0
637 then -- trace ("Descent " ++ show (desc - d) ++ " "
651 then -- trace ("Descent " ++ show (desc - d) ++ " "
638− -- ++ show (path, e)) $
652+ -- ++ show (path, e)) $
639 Total []
653 Total []
640− else Partial (Mutual (map (fst . fst) path ++ [f]))
654+ else Partial (Mutual (map (fst . fst . fst) path ++ [f]))
655+ | e `elem` map (fst . fst) path
656+ && not (f `elem` map fst es)
657+ = Partial (Mutual (map (fst . fst . fst) path ++ [f]))
641 | [Unchecked] <- lookupTotal f (tt_ctxt ist) =
658 | [Unchecked] <- lookupTotal f (tt_ctxt ist) =
642− let argspos = collapseNothing (zip nextargs [0..]) in
659+ let argspos = case collapseNothing (zip nextargs [0..]) of
643− collapse' Unchecked $
660+ [] -> [(Nothing, 0)]
661+ x -> x
662+-- trace (show (argspos, nextargs, path)) $
663+ pathres =
644 do (a, pos) <- argspos
664 do (a, pos) <- argspos
645 case a of
665 case a of
646 Nothing -> -- don't know, but if the
666 Nothing -> -- don't know, but if the
647 -- rest definitely terminates without
667 -- rest definitely terminates without
648 -- any cycles with route so far,
668 -- any cycles with route so far,
649 -- then we might yet be total
669 -- then we might yet be total
650− case collapse (map (tryPath (-10000) ((e, 0):path) es)
670+ case collapse (map (tryPath 0 (((e, arg), 0):path) es)
651 [0..length nextargs - 1]) of
671 [0..length nextargs - 1]) of
652 Total _ -> return Unchecked
672 Total _ -> return Unchecked
653 x -> return x
673 x -> return x
654 Just (nextarg, sc) ->
674 Just (nextarg, sc) ->
655 if nextarg == arg then
675 if nextarg == arg then
656 case sc of
676 case sc of
657− Same -> return $ tryPath desc ((e, desc) : path)
677+ Same -> return $ tryPath desc (((e, arg), desc) : path)
658 es pos
678 es pos
659 Smaller -> return $ tryPath (desc+1)
679 Smaller -> return $ tryPath (desc+1)
660− ((e, desc):path)
680+ (((e, arg), desc) : path)
661 es
681 es
662 pos
682 pos
663 _ -> trace ("Shouldn't happen " ++ show e) $
683 _ -> trace ("Shouldn't happen " ++ show e) $
664 return (Partial Itself)
684 return (Partial Itself)
665− else return Unchecked
685+ else return Unchecked in
686+-- trace (show (desc, argspos, path, es, pathres)) $
687+ collapse' Unchecked pathres
688+
666 | [Total a] <- lookupTotal f (tt_ctxt ist) = Total a
689 | [Total a] <- lookupTotal f (tt_ctxt ist) = Total a
667 | [Partial _] <- lookupTotal f (tt_ctxt ist) = Partial (Other [f])
690 | [Partial _] <- lookupTotal f (tt_ctxt ist) = Partial (Other [f])
668 | otherwise = Unchecked
691 | otherwise = Unchecked
@@ -671,8 +694,8 @@ allNothing xs = null (collapseNothing (zip xs [0..]))
671
694
672collapseNothing ((Nothing, _) : xs)
695collapseNothing ((Nothing, _) : xs)
673 = filter (\ (x, _) -> case x of
696 = filter (\ (x, _) -> case x of
674− Nothing -> False
697+ Nothing -> False
675− _ -> True) xs
698+ _ -> True) xs
676collapseNothing (x : xs) = x : collapseNothing xs
699collapseNothing (x : xs) = x : collapseNothing xs
677collapseNothing [] = []
700collapseNothing [] = []
678
701
src/Idris/DeepSeq.hs+3−23
@@ -13,7 +13,7 @@ instance NFData Raw where
13 rnf (RApp x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
13 rnf (RApp x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
14 rnf RType = ()
14 rnf RType = ()
15 rnf (RForce x1) = rnf x1 `seq` ()
15 rnf (RForce x1) = rnf x1 `seq` ()
16− rnf (RConstant x1) = rnf x1 `seq` ()
16+ rnf (RConstant x1) = x1 `seq` ()
17
17
18instance NFData FC where
18instance NFData FC where
19 rnf (FC x1 x2 x3) = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` ()
19 rnf (FC x1 x2 x3) = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` ()
@@ -32,26 +32,6 @@ instance NFData SpecialName where
32 rnf (MethodN x1) = rnf x1 `seq` ()
32 rnf (MethodN x1) = rnf x1 `seq` ()
33 rnf (CaseN x1) = rnf x1 `seq` ()
33 rnf (CaseN x1) = rnf x1 `seq` ()
34
34
35−instance NFData Const where
36− rnf (I x1) = rnf x1 `seq` ()
37− rnf (BI x1) = rnf x1 `seq` ()
38− rnf (Fl x1) = rnf x1 `seq` ()
39− rnf (Ch x1) = rnf x1 `seq` ()
40− rnf (Str x1) = rnf x1 `seq` ()
41− rnf (B8 x1) = rnf x1 `seq` ()
42− rnf (B16 x1) = rnf x1 `seq` ()
43− rnf (B32 x1) = rnf x1 `seq` ()
44− rnf (B64 x1) = rnf x1 `seq` ()
45− rnf (B8V x1) = rnf x1 `seq` ()
46− rnf (B16V x1) = rnf x1 `seq` ()
47− rnf (B32V x1) = rnf x1 `seq` ()
48− rnf (B64V x1) = rnf x1 `seq` ()
49− rnf (AType x1) = rnf x1 `seq` ()
50− rnf StrType = ()
51− rnf PtrType = ()
52− rnf VoidType = ()
53− rnf Forgot = ()
54−
55instance NFData IntTy where
35instance NFData IntTy where
56 rnf (ITFixed x1) = rnf x1 `seq` ()
36 rnf (ITFixed x1) = rnf x1 `seq` ()
57 rnf ITNative = ()
37 rnf ITNative = ()
@@ -132,7 +112,7 @@ instance (NFData n) => NFData (TT n) where
132 rnf (V x1) = rnf x1 `seq` ()
112 rnf (V x1) = rnf x1 `seq` ()
133 rnf (Bind x1 x2 x3) = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` ()
113 rnf (Bind x1 x2 x3) = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` ()
134 rnf (App x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
114 rnf (App x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
135− rnf (Constant x1) = rnf x1 `seq` ()
115+ rnf (Constant x1) = x1 `seq` ()
136 rnf (Proj x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
116 rnf (Proj x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
137 rnf Erased = ()
117 rnf Erased = ()
138 rnf Impossible = ()
118 rnf Impossible = ()
@@ -271,7 +251,7 @@ instance NFData PTerm where
271 rnf PType = ()
251 rnf PType = ()
272 rnf (PGoal x1 x2 x3 x4)
252 rnf (PGoal x1 x2 x3 x4)
273 = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` rnf x4 `seq` ()
253 = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` rnf x4 `seq` ()
274− rnf (PConstant x1) = rnf x1 `seq` ()
254+ rnf (PConstant x1) = x1 `seq` ()
275 rnf Placeholder = ()
255 rnf Placeholder = ()
276 rnf (PDoBlock x1) = rnf x1 `seq` ()
256 rnf (PDoBlock x1) = rnf x1 `seq` ()
277 rnf (PIdiom x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
257 rnf (PIdiom x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
src/Idris/Delaborate.hs+15−8
@@ -14,21 +14,27 @@ import Debug.Trace
14bugaddr = "https://github.com/idris-lang/Idris-dev/issues"
14bugaddr = "https://github.com/idris-lang/Idris-dev/issues"
15
15
16delab :: IState -> Term -> PTerm
16delab :: IState -> Term -> PTerm
17−delab i tm = delab' i tm False
17+delab i tm = delab' i tm False False
18+
19+delabMV :: IState -> Term -> PTerm
20+delabMV i tm = delab' i tm False True
18
21
19delabTy :: IState -> Name -> PTerm
22delabTy :: IState -> Name -> PTerm
20delabTy i n
23delabTy i n
21 = case lookupTy n (tt_ctxt i) of
24 = case lookupTy n (tt_ctxt i) of
22 (ty:_) -> case lookupCtxt n (idris_implicits i) of
25 (ty:_) -> case lookupCtxt n (idris_implicits i) of
23− (imps:_) -> delabTy' i imps ty False
26+ (imps:_) -> delabTy' i imps ty False False
24− _ -> delabTy' i [] ty False
27+ _ -> delabTy' i [] ty False False
25
28
26−delab' :: IState -> Term -> Bool -> PTerm
29+delab' :: IState -> Term -> Bool -> Bool -> PTerm
27−delab' i t f = delabTy' i [] t f
30+delab' i t f mvs = delabTy' i [] t f mvs
28
31
29delabTy' :: IState -> [PArg] -- ^ implicit arguments to type, if any
32delabTy' :: IState -> [PArg] -- ^ implicit arguments to type, if any
33+ -> Term
34+ -> Bool -- ^ use full names
35+ -> Bool -- ^ Don't treat metavariables specially
30− -> Term -> Bool -> PTerm
36+ -> PTerm
31−delabTy' ist imps tm fullname = de [] imps tm
37+delabTy' ist imps tm fullname mvs = de [] imps tm
32 where
38 where
33 un = fileFC "(val)"
39 un = fileFC "(val)"
34
40
@@ -84,11 +90,12 @@ delabTy' ist imps tm fullname = de [] imps tm
84 | n == eqTy = PEq un (de env [] l) (de env [] r)
90 | n == eqTy = PEq un (de env [] l) (de env [] r)
85 | n == UN "Ex_intro" = PDPair un (de env [] l) Placeholder
91 | n == UN "Ex_intro" = PDPair un (de env [] l) Placeholder
86 (de env [] r)
92 (de env [] r)
87− deFn env (P _ n _) args
93+ deFn env (P _ n _) args | not mvs
88 = case lookup n (idris_metavars ist) of
94 = case lookup n (idris_metavars ist) of
89 Just (Just _, mi, _) ->
95 Just (Just _, mi, _) ->
90 mkMVApp (dens n) (drop mi (map (de env []) args))
96 mkMVApp (dens n) (drop mi (map (de env []) args))
91 _ -> mkPApp (dens n) (map (de env []) args)
97 _ -> mkPApp (dens n) (map (de env []) args)
98+ | otherwise = mkPApp (dens n) (map (de env []) args)
92 deFn env f args = PApp un (de env [] f) (map pexp (map (de env []) args))
99 deFn env f args = PApp un (de env [] f) (map pexp (map (de env []) args))
93
100
94 mkMVApp n []
101 mkMVApp n []
src/Idris/ElabDecls.hs+41−29
@@ -613,11 +613,9 @@ elabClauses info fc opts n_in cs = let n = liftname info n_in in
613 -- Look for 'static' names and generate new specialised
613 -- Look for 'static' names and generate new specialised
614 -- definitions for them
614 -- definitions for them
615
615
616− {-
617 mapM_ (\ e -> case e of
616 mapM_ (\ e -> case e of
618 Left _ -> return ()
617 Left _ -> return ()
619 Right (l, r) -> elabPE info fc n r) pats
618 Right (l, r) -> elabPE info fc n r) pats
620− -}
621
619
622 -- NOTE: Need to store original definition so that proofs which
620 -- NOTE: Need to store original definition so that proofs which
623 -- rely on its structure aren't affected by any changes to the
621 -- rely on its structure aren't affected by any changes to the
@@ -707,7 +705,8 @@ elabClauses info fc opts n_in cs = let n = liftname info n_in in
707 pdef pdef pdef_inl pdef' ty)
705 pdef pdef pdef_inl pdef' ty)
708 addIBC (IBCDef n)
706 addIBC (IBCDef n)
709 setTotality n tot
707 setTotality n tot
710− when (not reflect) $ totcheck (fc, n)
708+ when (not reflect) $ do totcheck (fc, n)
709+ defer_totcheck (fc, n)
711 when (tot /= Unchecked) $ addIBC (IBCTotal n tot)
710 when (tot /= Unchecked) $ addIBC (IBCTotal n tot)
712 i <- getIState
711 i <- getIState
713 case lookupDef n (tt_ctxt i) of
712 case lookupDef n (tt_ctxt i) of
@@ -729,7 +728,7 @@ elabClauses info fc opts n_in cs = let n = liftname info n_in in
729 [] -> return ()
728 [] -> return ()
730 return ()
729 return ()
731 where
730 where
732− noMatch i cs tm = all (\x -> case matchClause i (delab' i x True) tm of
731+ noMatch i cs tm = all (\x -> case matchClause i (delab' i x True True) tm of
733 Right _ -> False
732 Right _ -> False
734 Left miss -> True) cs
733 Left miss -> True) cs
735
734
@@ -789,36 +788,40 @@ elabPE info fc caller r =
789 let sa = getSpecApps ist [] r
788 let sa = getSpecApps ist [] r
790 mapM_ (mkSpecialised ist) sa
789 mapM_ (mkSpecialised ist) sa
791 where
790 where
792− -- TODO: Freeze the newly defined name, make sure it never gets
793− -- reduced when specialising (not quite the same as an 'abstract' name
794− -- so may need a new class (public/abstract/private/specialised)
795−
796− -- Add a PTerm level transformation rule, which is basically the
791+ -- TODO: Add a PTerm level transformation rule, which is basically the
797 -- new definition in reverse (before specialising it).
792 -- new definition in reverse (before specialising it).
798 -- RHS => LHS where implicit arguments are left blank in the
793 -- RHS => LHS where implicit arguments are left blank in the
799 -- transformation.
794 -- transformation.
800
795
801 -- Apply that transformation after every PClauses elaboration
796 -- Apply that transformation after every PClauses elaboration
802
797
803− mkSpecialised ist specapp = do
798+ mkSpecialised ist specapp_in = do
804− iputStrLn (show specapp)
799+ let (specTy, specapp) = getSpecTy ist specapp_in
805− let specTy = getSpecTy ist specapp
806 let (n, newnm, [(lhs, rhs)]) = getSpecClause ist specapp
800 let (n, newnm, [(lhs, rhs)]) = getSpecClause ist specapp
807 let undef = case lookupDef newnm (tt_ctxt ist) of
801 let undef = case lookupDef newnm (tt_ctxt ist) of
808 [] -> True
802 [] -> True
809 _ -> False
803 _ -> False
810− iputStrLn $ show (newnm, map (concreteArg ist) (snd specapp))
804+ logLvl 5 $ show (newnm, map (concreteArg ist) (snd specapp))
805+ idrisCatch
811− when (undef && all (concreteArg ist) (snd specapp)) $ do
806+ (when (undef && all (concreteArg ist) (snd specapp)) $ do
807+ cgns <- getAllNames n
812− let opts = [Specialise ((n, Nothing) :
808+ let opts = [Specialise (map (\x -> (x, Nothing)) cgns ++
813− (mapMaybe specName (snd specapp)))]
809+ mapMaybe specName (snd specapp))]
814− iputStrLn (show specapp)
810+ logLvl 3 $ "Specialising application: " ++ show specapp
811+ logLvl 2 $ "New name: " ++ show newnm
815− iputStrLn $ "PE definition type : " ++ (show specTy)
812+ iLOG $ "PE definition type : " ++ (show specTy)
816 ++ "\n" ++ show opts
813 ++ "\n" ++ show opts
817− iputStrLn $ "PE definition " ++ show newnm ++ ":\n" ++
814+ logLvl 2 $ "PE definition " ++ show newnm ++ ":\n" ++
818− (show lhs ++ " = " ++ show rhs)
815+ (showImp Nothing True False lhs ++ " = " ++
816+ showImp Nothing True False rhs)
819 elabType info defaultSyntax "" fc opts newnm specTy
817 elabType info defaultSyntax "" fc opts newnm specTy
820 let def = [PClause fc newnm lhs [] rhs []]
818 let def = [PClause fc newnm lhs [] rhs []]
821 elabClauses info fc opts newnm def
819 elabClauses info fc opts newnm def
820+ logLvl 1 $ "Specialised " ++ show newnm)
821+ -- if it doesn't work, just don't specialise. Could happen for lots
822+ -- of valid reasons (e.g. local variables in scope which can't be
823+ -- lifted out).
824+ (\e -> logLvl 4 $ "Couldn't specialise: " ++ (pshow ist e))
822
825
823 specName (ImplicitS, tm)
826 specName (ImplicitS, tm)
824 | (P Ref n _, _) <- unApply tm = Just (n, Just 1)
827 | (P Ref n _, _) <- unApply tm = Just (n, Just 1)
@@ -840,17 +843,21 @@ elabPE info fc caller r =
840 -- get the type of a specialised application
843 -- get the type of a specialised application
841 getSpecTy ist (n, args)
844 getSpecTy ist (n, args)
842 = case lookupTy n (tt_ctxt ist) of
845 = case lookupTy n (tt_ctxt ist) of
846+ [ty] -> let (specty_in, args') = specType args (explicitNames ty)
843− [ty] -> let specty = normalise (tt_ctxt ist) [] (specType args ty) in
847+ specty = normalise (tt_ctxt ist) [] (finalise specty_in)
844− trace (show specty) $ mkPE_TyDecl ist args
845− (explicitNames specty)
848+ t = mkPE_TyDecl ist args' (explicitNames specty) in
849+ (t, (n, args'))
846-- (normalise (tt_ctxt ist) [] (specType args ty))
850-- (normalise (tt_ctxt ist) [] (specType args ty))
847 _ -> error "Can't happen (getSpecTy)"
851 _ -> error "Can't happen (getSpecTy)"
848
852
849 getSpecClause ist (n, args)
853 getSpecClause ist (n, args)
850− = let newnm = UN (show (nsroot n) ++ "_" ++ show (nsroot caller) ++
854+ = let newnm = UN ("__"++show (nsroot n) ++ "_" ++
855+ showSep "_" (map showArg args)) in
851− "__spectest") in -- UN (show n ++ show (map snd args)) in
856+ -- UN (show n ++ show (map snd args)) in
852 (n, newnm, mkPE_TermDecl ist newnm n args)
857 (n, newnm, mkPE_TermDecl ist newnm n args)
853−
858+ where showArg (ExplicitS, n) = show n
859+ showArg (ImplicitS, n) = show n
860+ showArg _ = ""
854
861
855
862
856-- Elaborate a value, returning any new bindings created (this will only
863-- Elaborate a value, returning any new bindings created (this will only
@@ -953,9 +960,11 @@ elabClause info opts (cnum, PClause fc fname lhs_in withs rhs_in whereblock)
953
960
954 (clhs_c, clhsty) <- recheckC fc [] lhs_tm
961 (clhs_c, clhsty) <- recheckC fc [] lhs_tm
955 let clhs = normalise ctxt [] clhs_c
962 let clhs = normalise ctxt [] clhs_c
963+
964+ logLvl 3 ("Normalised LHS: " ++ showImp Nothing True False (delabMV i clhs))
956
965
957− addInternalApp (fc_fname fc) (fc_line fc) (delab i clhs)
966+ addInternalApp (fc_fname fc) (fc_line fc) (delabMV i clhs)
958− addIBC (IBCLineApp (fc_fname fc) (fc_line fc) (delab i clhs))
967+ addIBC (IBCLineApp (fc_fname fc) (fc_line fc) (delabMV i clhs))
959
968
960 logLvl 5 ("Checked " ++ show clhs ++ "\n" ++ show clhsty)
969 logLvl 5 ("Checked " ++ show clhs ++ "\n" ++ show clhsty)
961 -- Elaborate where block
970 -- Elaborate where block
@@ -999,6 +1008,9 @@ elabClause info opts (cnum, PClause fc fname lhs_in withs rhs_in whereblock)
999 let def'' = map (\(n, (i, top, t)) -> (n, (i, top, t, False))) def'
1008 let def'' = map (\(n, (i, top, t)) -> (n, (i, top, t, False))) def'
1000 addDeferred def''
1009 addDeferred def''
1001
1010
1011+ when (not (null def')) $ do
1012+ mapM_ defer_totcheck (map (\x -> (fc, fst x)) def'')
1013+
1002 -- Now the remaining deferred (i.e. no type declarations) clauses
1014 -- Now the remaining deferred (i.e. no type declarations) clauses
1003 -- from the where block
1015 -- from the where block
1004
1016
@@ -1013,7 +1025,7 @@ elabClause info opts (cnum, PClause fc fname lhs_in withs rhs_in whereblock)
1013 OK _ -> return ()
1025 OK _ -> return ()
1014 Error e -> ierror (At fc (CantUnify False clhsty crhsty e [] 0))
1026 Error e -> ierror (At fc (CantUnify False clhsty crhsty e [] 0))
1015 i <- getIState
1027 i <- getIState
1016− checkInferred fc (delab' i crhs True) rhs
1028+ checkInferred fc (delab' i crhs True True) rhs
1017 return $ Right (clhs, crhs)
1029 return $ Right (clhs, crhs)
1018 where
1030 where
1019 decorate (NS x ns)
1031 decorate (NS x ns)
src/Idris/ElabTerm.hs+1−1
@@ -653,7 +653,7 @@ resolveTC :: Int -> Name -> IState -> ElabD ()
653resolveTC 0 fn ist = fail $ "Can't resolve type class"
653resolveTC 0 fn ist = fail $ "Can't resolve type class"
654resolveTC 1 fn ist = try' (trivial' ist) (resolveTC 0 fn ist) True
654resolveTC 1 fn ist = try' (trivial' ist) (resolveTC 0 fn ist) True
655resolveTC depth fn ist
655resolveTC depth fn ist
656− = do compute
656+ = do hnf_compute
657 g <- goal
657 g <- goal
658 ptm <- get_term
658 ptm <- get_term
659 hs <- get_holes
659 hs <- get_holes
src/Idris/Help.hs+3−1
@@ -60,10 +60,12 @@ extraHelp =
60 , ([":casesplit!", ":cs!"], NoArg, ":cs! <line> <name> destructively splits the pattern variable on the line")
60 , ([":casesplit!", ":cs!"], NoArg, ":cs! <line> <name> destructively splits the pattern variable on the line")
61 , ([":addclause", ":ac"], NoArg, ":ac <line> <name> adds a clause for the definition of the name on the line")
61 , ([":addclause", ":ac"], NoArg, ":ac <line> <name> adds a clause for the definition of the name on the line")
62 , ([":addclause!", ":ac!"], NoArg, ":ac! <line> <name> destructively adds a clause for the definition of the name on the line")
62 , ([":addclause!", ":ac!"], NoArg, ":ac! <line> <name> destructively adds a clause for the definition of the name on the line")
63+ , ([":addmissing", ":am"], NoArg, ":am <line> <name> adds all missing pattern matches for the name on the line")
64+ , ([":addmissing!", ":am!"], NoArg, ":am! <line> <name> destructively adds all missing pattern matches for the name on the line")
63 , ([":makewith", ":mw"], NoArg, ":mw <line> <name> adds a with clause for the definition of the name on the line")
65 , ([":makewith", ":mw"], NoArg, ":mw <line> <name> adds a with clause for the definition of the name on the line")
64 , ([":makewith!", ":mw!"], NoArg, ":mw! <line> <name> destructively adds a with clause for the definition of the name on the line")
66 , ([":makewith!", ":mw!"], NoArg, ":mw! <line> <name> destructively adds a with clause for the definition of the name on the line")
65 , ([":proofsearch", ":ps"], NoArg, ":ps <line> <name> <names> does proof search for name on line, with names as hints")
67 , ([":proofsearch", ":ps"], NoArg, ":ps <line> <name> <names> does proof search for name on line, with names as hints")
66 , ([":proofsearch!", ":ps!"], NoArg, ":ps! <line> <name> <names> destructively does proof search for name on line, with names as hints")
68 , ([":proofsearch!", ":ps!"], NoArg, ":ps! <line> <name> <names> destructively does proof search for name on line, with names as hints")
67 , ([":addproofclause", ":apc"], NoArg, ":apc <line> <name> adds a pattern-matching proof clause to name on line")
69 , ([":addproofclause", ":apc"], NoArg, ":apc <line> <name> adds a pattern-matching proof clause to name on line")
68 , ([":addproofclause!", ":apc!"], NoArg, ":apc! <line> <name> destructively adds a pattern-matching proof clause to name on line")
70 , ([":addproofclause!", ":apc!"], NoArg, ":apc! <line> <name> destructively adds a pattern-matching proof clause to name on line")
69− ]
71+ ]
src/Idris/ParseExpr.hs+5−10
@@ -1,4 +1,5 @@
1{-# LANGUAGE GeneralizedNewtypeDeriving, ConstraintKinds, PatternGuards #-}
1{-# LANGUAGE GeneralizedNewtypeDeriving, ConstraintKinds, PatternGuards #-}
2+{-# OPTIONS_GHC -O0 #-}
2module Idris.ParseExpr where
3module Idris.ParseExpr where
3
4
4import Prelude hiding (pi)
5import Prelude hiding (pi)
@@ -685,7 +686,6 @@ Pi ::=
685 | '|'? Static? '{' TypeDeclList '}' '->' Expr
686 | '|'? Static? '{' TypeDeclList '}' '->' Expr
686 | '{' 'auto' TypeDeclList '}' '->' Expr
687 | '{' 'auto' TypeDeclList '}' '->' Expr
687 | '{' 'default' TypeDeclList '}' '->' Expr
688 | '{' 'default' TypeDeclList '}' '->' Expr
688− | '{' 'static' '}' Expr' '->' Expr
689 ;
689 ;
690 -}
690 -}
691
691
@@ -708,7 +708,8 @@ pi syn =
708 symbol "->"
708 symbol "->"
709 sc <- expr syn
709 sc <- expr syn
710 return (bindList (PPi
710 return (bindList (PPi
711− (TacImp False Dynamic (PTactics [Trivial]) "")) xt sc)) <|> (do
711+ (TacImp False Dynamic (PTactics [Trivial]) "")) xt sc))
712+ <|> (do
712 reserved "default"
713 reserved "default"
713 when (lazy || (st == Static)) $ fail "default tactic constraints can not be lazy or static"
714 when (lazy || (st == Static)) $ fail "default tactic constraints can not be lazy or static"
714 script <- simpleExpr syn
715 script <- simpleExpr syn
@@ -716,14 +717,8 @@ pi syn =
716 lchar '}'
717 lchar '}'
717 symbol "->"
718 symbol "->"
718 sc <- expr syn
719 sc <- expr syn
719− return (bindList (PPi (TacImp False Dynamic script "")) xt sc)) <|> (do
720+ return (bindList (PPi (TacImp False Dynamic script "")) xt sc))
720− reserved "static"
721− lchar '}'
722− t <- expr' syn
723− symbol "->"
724− sc <- expr syn
725− return (PPi (Exp False Static "" False) (MN 42 "__pi_arg") t sc)) <|> (
726− if implicitAllowed syn then do
721+ <|> (if implicitAllowed syn then do
727 xt <- typeDeclList syn
722 xt <- typeDeclList syn
728 lchar '}'
723 lchar '}'
729 symbol "->"
724 symbol "->"
src/Idris/Parser.hs+9
@@ -1,4 +1,5 @@
1{-# LANGUAGE GeneralizedNewtypeDeriving, ConstraintKinds, PatternGuards #-}
1{-# LANGUAGE GeneralizedNewtypeDeriving, ConstraintKinds, PatternGuards #-}
2+{-# OPTIONS_GHC -O0 #-}
2module Idris.Parser(module Idris.Parser,
3module Idris.Parser(module Idris.Parser,
3 module Idris.ParseExpr,
4 module Idris.ParseExpr,
4 module Idris.ParseData,
5 module Idris.ParseData,
@@ -1042,6 +1043,14 @@ loadSource h lidr f
1042 i <- getIState
1043 i <- getIState
1043 mapM_ buildSCG (idris_totcheck i)
1044 mapM_ buildSCG (idris_totcheck i)
1044 mapM_ checkDeclTotality (idris_totcheck i)
1045 mapM_ checkDeclTotality (idris_totcheck i)
1046+
1047+ -- Redo totality check for deferred names
1048+ let deftots = idris_defertotcheck i
1049+ iLOG $ "Totality checking " ++ show deftots
1050+ mapM_ (\x -> setTotality x Unchecked) (map snd deftots)
1051+ mapM_ buildSCG deftots
1052+ mapM_ checkDeclTotality deftots
1053+
1045 iLOG ("Finished " ++ f)
1054 iLOG ("Finished " ++ f)
1046 ibcsd <- valIBCSubDir i
1055 ibcsd <- valIBCSubDir i
1047 iLOG "Universe checking"
1056 iLOG "Universe checking"
src/Idris/PartialEval.hs+48−20
@@ -9,6 +9,7 @@ import Idris.Delaborate
9import Idris.Core.TT
9import Idris.Core.TT
10import Idris.Core.Evaluate
10import Idris.Core.Evaluate
11
11
12+import Control.Monad.State
12import Debug.Trace
13import Debug.Trace
13
14
14partial_eval :: Context -> [(Name, Maybe Int)] ->
15partial_eval :: Context -> [(Name, Maybe Int)] ->
@@ -23,26 +24,52 @@ partial_eval ctxt ns tms = map peClause tms where
23 toLimit (n, Nothing) = (n, 65536) -- somewhat arbitrary reduction limit
24 toLimit (n, Nothing) = (n, 65536) -- somewhat arbitrary reduction limit
24 toLimit (n, Just l) = (n, l)
25 toLimit (n, Just l) = (n, l)
25
26
26−specType :: [(PEArgType, Term)] -> Type -> Type
27+specType :: [(PEArgType, Term)] -> Type -> (Type, [(PEArgType, Term)])
28+specType args ty = let (t, args') = runState (unifyEq args ty) [] in
29+ (st (map fst args') t, map fst args')
30+ where
27−specType ((ExplicitS, v) : xs) (Bind n (Pi t) sc)
31+ st ((ExplicitS, v) : xs) (Bind n (Pi t) sc)
28− = Bind n (Let t v) (specType xs sc)
32+ = Bind n (Let t v) (st xs sc)
29−specType ((ImplicitS, v) : xs) (Bind n (Pi t) sc)
33+ st ((ImplicitS, v) : xs) (Bind n (Pi t) sc)
30− = Bind n (Let t v) (specType xs sc)
34+ = Bind n (Let t v) (st xs sc)
35+ st ((UnifiedD, _) : xs) (Bind n (Pi t) sc)
36+ = st xs sc
31−specType (_ : xs) (Bind n (Pi t) sc)
37+ st (_ : xs) (Bind n (Pi t) sc)
32− = Bind n (Pi t) (specType xs sc)
38+ = Bind n (Pi t) (st xs sc)
33−specType _ t = t
39+ st _ t = t
40+
41+ unifyEq (imp@(ImplicitD, v) : xs) (Bind n (Pi t) sc)
42+ = do amap <- get
43+ case lookup imp amap of
44+ Just n' ->
45+ do put (amap ++ [((UnifiedD, Erased), n)])
46+ sc' <- unifyEq xs (subst n (P Bound n' Erased) sc)
47+ return (Bind n (Pi t) sc') -- erase later
48+ _ -> do put (amap ++ [(imp, n)])
49+ sc' <- unifyEq xs sc
50+ return (Bind n (Pi t) sc')
51+ unifyEq (x : xs) (Bind n (Pi t) sc)
52+ = do args <- get
53+ put (args ++ [(x, n)])
54+ sc' <- unifyEq xs sc
55+ return (Bind n (Pi t) sc')
56+ unifyEq xs t = do args <- get
57+ put (args ++ (zip xs (repeat (UN "_"))))
58+ return t
34
59
35mkPE_TyDecl :: IState -> [(PEArgType, Term)] -> Type -> PTerm
60mkPE_TyDecl :: IState -> [(PEArgType, Term)] -> Type -> PTerm
61+mkPE_TyDecl ist args ty = mkty args ty
62+ where
36−mkPE_TyDecl ist ((ExplicitD, v) : xs) (Bind n (Pi t) sc)
63+ mkty ((ExplicitD, v) : xs) (Bind n (Pi t) sc)
37− = PPi expl n (delab ist t) (mkPE_TyDecl ist xs sc)
64+ = PPi expl n (delab ist t) (mkty xs sc)
38−mkPE_TyDecl ist ((ImplicitD, v) : xs) (Bind n (Pi t) sc)
65+ mkty ((ImplicitD, v) : xs) (Bind n (Pi t) sc)
39− | concreteClass ist t = mkPE_TyDecl ist xs sc
66+ | concreteClass ist t = mkty xs sc
40− | classConstraint ist t
67+ | classConstraint ist t
41− = PPi constraint n (delab ist t) (mkPE_TyDecl ist xs sc)
68+ = PPi constraint n (delab ist t) (mkty xs sc)
42− | otherwise = PPi impl n (delab ist t) (mkPE_TyDecl ist xs sc)
69+ | otherwise = PPi impl n (delab ist t) (mkty xs sc)
43−mkPE_TyDecl ist (_ : xs) t
70+ mkty (_ : xs) t
44− = mkPE_TyDecl ist xs t
71+ = mkty xs t
45−mkPE_TyDecl ist [] t = delab ist t
72+ mkty [] t = delab ist t
46
73
47classConstraint ist v
74classConstraint ist v
48 | (P _ c _, args) <- unApply v = case lookupCtxt c (idris_classes ist) of
75 | (P _ c _, args) <- unApply v = case lookupCtxt c (idris_classes ist) of
@@ -81,7 +108,8 @@ mkPE_TermDecl ist newname sname ns
81
108
82data PEArgType = ImplicitS | ImplicitD
109data PEArgType = ImplicitS | ImplicitD
83 | ExplicitS | ExplicitD
110 | ExplicitS | ExplicitD
111+ | UnifiedD
84− deriving Show
112+ deriving (Eq, Show)
85
113
86getSpecApps :: IState -> [Name] -> Term ->
114getSpecApps :: IState -> [Name] -> Term ->
87 [(Name, [(PEArgType, Term)])]
115 [(Name, [(PEArgType, Term)])]
@@ -94,7 +122,7 @@ getSpecApps ist env tm = ga env (explicitNames tm) where
94 | x && imparg imp = (ImplicitS, tm)
122 | x && imparg imp = (ImplicitS, tm)
95 | x = (ExplicitS, tm)
123 | x = (ExplicitS, tm)
96 | imparg imp = (ImplicitD, tm)
124 | imparg imp = (ImplicitD, tm)
97− | otherwise = (ExplicitD, (P Ref (MN n "arg") Erased))
125+ | otherwise = (ExplicitD, (P Ref (UN (show n ++ "arg")) Erased))
98
126
99 imparg (PExp _ _ _ _) = False
127 imparg (PExp _ _ _ _) = False
100 imparg _ = True
128 imparg _ = True
src/Idris/REPL.hs+17−3
@@ -275,6 +275,7 @@ ideslaveProcess fn (Spec t) = process stdout fn (Spec t)
275ideslaveProcess fn (ShowProof n') = process stdout fn (ShowProof n')
275ideslaveProcess fn (ShowProof n') = process stdout fn (ShowProof n')
276ideslaveProcess fn (HNF t) = process stdout fn (HNF t)
276ideslaveProcess fn (HNF t) = process stdout fn (HNF t)
277--ideslaveProcess fn TTShell = process stdout fn TTShell -- need some prove mode!
277--ideslaveProcess fn TTShell = process stdout fn TTShell -- need some prove mode!
278+ideslaveProcess fn (TestInline t) = process stdout fn (TestInline t)
278
279
279--that most likely does not work, since we need to wrap
280--that most likely does not work, since we need to wrap
280--input/output of the executed binary...
281--input/output of the executed binary...
@@ -301,6 +302,12 @@ ideslaveProcess fn (UnsetOpt ShowImpl) = do process stdout fn (UnsetOpt ShowImpl
301 iPrintResult ""
302 iPrintResult ""
302ideslaveProcess fn (SetOpt x) = process stdout fn (SetOpt x)
303ideslaveProcess fn (SetOpt x) = process stdout fn (SetOpt x)
303ideslaveProcess fn (UnsetOpt x) = process stdout fn (UnsetOpt x)
304ideslaveProcess fn (UnsetOpt x) = process stdout fn (UnsetOpt x)
305+ideslaveProcess fn (CaseSplitAt False pos str) = process stdout fn (CaseSplitAt False pos str)
306+ideslaveProcess fn (AddProofClauseFrom False pos str) = process stdout fn (AddProofClauseFrom False pos str)
307+ideslaveProcess fn (AddClauseFrom False pos str) = process stdout fn (AddClauseFrom False pos str)
308+ideslaveProcess fn (AddMissing False pos str) = process stdout fn (AddMissing False pos str)
309+ideslaveProcess fn (MakeWith False pos str) = process stdout fn (MakeWith False pos str)
310+ideslaveProcess fn (DoProofSearch False pos str xs) = process stdout fn (DoProofSearch False pos str xs)
304ideslaveProcess fn _ = iPrintError "command not recognized or not supported"
311ideslaveProcess fn _ = iPrintError "command not recognized or not supported"
305
312
306
313
@@ -658,9 +665,12 @@ process h fn (AddMissing updatefile l n)
658process h fn (MakeWith updatefile l n)
665process h fn (MakeWith updatefile l n)
659 = do src <- runIO $ readFile fn
666 = do src <- runIO $ readFile fn
660 let (before, tyline : later) = splitAt (l-1) (lines src)
667 let (before, tyline : later) = splitAt (l-1) (lines src)
668+ let ind = getIndent tyline
661 let with = mkWith tyline n
669 let with = mkWith tyline n
662− -- add clause before first blank line in 'later'
670+ -- add clause before first blank line in 'later',
671+ -- or (TODO) before first line with same indentation as tyline
663− let (nonblank, rest) = span (not . all isSpace) later
672+ let (nonblank, rest) = span (\x -> not (all isSpace x) &&
673+ not (ind == getIndent x)) later
664 if updatefile then
674 if updatefile then
665 do let fb = fn ++ "~"
675 do let fb = fn ++ "~"
666 runIO $ writeFile fb (unlines (before ++ nonblank)
676 runIO $ writeFile fb (unlines (before ++ nonblank)
@@ -668,6 +678,8 @@ process h fn (MakeWith updatefile l n)
668 unlines rest)
678 unlines rest)
669 runIO $ copyFile fb fn
679 runIO $ copyFile fb fn
670 else ihPrintResult h with
680 else ihPrintResult h with
681+ where getIndent s = length (takeWhile isSpace s)
682+
671process h fn (DoProofSearch updatefile l n hints)
683process h fn (DoProofSearch updatefile l n hints)
672 = do src <- runIO $ readFile fn
684 = do src <- runIO $ readFile fn
673 let (before, tyline : later) = splitAt (l-1) (lines src)
685 let (before, tyline : later) = splitAt (l-1) (lines src)
@@ -937,6 +949,7 @@ parseCodegen _ = error "unknown codegen" -- FIXME: partial function
937
949
938parseArgs :: [String] -> [Opt]
950parseArgs :: [String] -> [Opt]
939parseArgs [] = []
951parseArgs [] = []
952+parseArgs ("--nobanner":ns) = NoBanner : (parseArgs ns)
940parseArgs ("--quiet":ns) = Quiet : (parseArgs ns)
953parseArgs ("--quiet":ns) = Quiet : (parseArgs ns)
941parseArgs ("--ideslave":ns) = Ideslave : (parseArgs ns)
954parseArgs ("--ideslave":ns) = Ideslave : (parseArgs ns)
942parseArgs ("--client":ns) = [Client (showSep " " ns)]
955parseArgs ("--client":ns) = [Client (showSep " " ns)]
@@ -1078,6 +1091,7 @@ idrisMain :: [Opt] -> Idris ()
1078idrisMain opts =
1091idrisMain opts =
1079 do let inputs = opt getFile opts
1092 do let inputs = opt getFile opts
1080 let quiet = Quiet `elem` opts
1093 let quiet = Quiet `elem` opts
1094+ let nobanner = NoBanner `elem` opts
1081 let idesl = Ideslave `elem` opts
1095 let idesl = Ideslave `elem` opts
1082 let runrepl = not (NoREPL `elem` opts)
1096 let runrepl = not (NoREPL `elem` opts)
1083 let output = opt getOutput opts
1097 let output = opt getOutput opts
@@ -1139,7 +1153,7 @@ idrisMain opts =
1139 return ()
1153 return ()
1140 when (not (NoPrelude `elem` opts)) $ do x <- loadModule stdout "Prelude"
1154 when (not (NoPrelude `elem` opts)) $ do x <- loadModule stdout "Prelude"
1141 return ()
1155 return ()
1142− when (runrepl && not quiet && not idesl && not (isJust script)) $ iputStrLn banner
1156+ when (runrepl && not quiet && not idesl && not (isJust script) && not nobanner) $ iputStrLn banner
1143 ist <- getIState
1157 ist <- getIState
1144
1158
1145 loadInputs stdout inputs
1159 loadInputs stdout inputs
src/Util/System.hs+9−1
@@ -76,8 +76,16 @@ extraLib = " -L/usr/local/lib"
76#else
76#else
77extraLib = ""
77extraLib = ""
78#endif
78#endif
79+
80+#ifdef IDRIS_GMP
81+gmpLib = " -lgmp"
82+#else
83+gmpLib = ""
84+#endif
85+
79getLibFlags = do dir <- getDataDir
86getLibFlags = do dir <- getDataDir
87+ return $ "-L" ++ (dir </> "rts") ++
80− return $ "-L" ++ (dir </> "rts") ++ " -lidris_rts" ++ extraLib ++ " -lgmp -lpthread"
88+ " -lidris_rts" ++ extraLib ++ gmpLib ++ " -lpthread"
81
89
82getIdrisLibDir = do dir <- getDataDir
90getIdrisLibDir = do dir <- getDataDir
83 return $ addTrailingPathSeparator dir
91 return $ addTrailingPathSeparator dir
test/reg005/reg005.idr+1−1
@@ -30,7 +30,7 @@ compress xs with (rle xs)
30 compress Nil | REnd = ""
30 compress Nil | REnd = ""
31 compress (rep (S n) x ++ xs) | RChar _ _ rs
31 compress (rep (S n) x ++ xs) | RChar _ _ rs
32 = let ni : Integer = cast (S n) in
32 = let ni : Integer = cast (S n) in
33− show ni ++ show x ++ compress xs
33+ show ni ++ strCons x (compress xs)
34
34
35compressString : String -> String
35compressString : String -> String
36compressString xs = compress (fromList (unpack xs))
36compressString xs = compress (fromList (unpack xs))
test/reg006/run+1−1
@@ -1,3 +1,3 @@
1#!/usr/bin/env bash
1#!/usr/bin/env bash
2−idris $@ reg006.idr -o reg006
2+idris $@ reg006.idr --check
3rm -f *.ibc
3rm -f *.ibc
test/reg024/reg024.idr+1−1
@@ -28,4 +28,4 @@ test : String
28test = printf "The %s is %d" "answer" 42
28test = printf "The %s is %d" "answer" 42
29
29
30main : IO ()
30main : IO ()
31−main = print test
31+main = putStrLn test
test/reg025/reg025.idr+2−2
@@ -70,6 +70,6 @@ emptyCell (MkBoard rs) =
70main : IO ()
70main : IO ()
71main =
71main =
72 case emptyCell (emptyBoard {n=0}) of
72 case emptyCell (emptyBoard {n=0}) of
73− Left _ => print "l"
73+ Left _ => putStrLn "l"
74− Right _ => print "r"
74+ Right _ => putStrLn "r"
75
75
test/reg028/expectednew file+2
@@ -0,0 +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}
test/reg028/reg028.idrnew file+8
@@ -0,0 +1,8 @@
1+module tbad
2+
3+total
4+bad : Nat -> Nat
5+bad Z = Z
6+bad (S m) with (succ m)
7+ bad _ | j = bad j
8+
test/reg028/reg028a.idrnew file+25
@@ -0,0 +1,25 @@
1+module tbad
2+
3+partial
4+qsort : Ord a => List a -> List a
5+qsort [] = []
6+qsort (x::xs) with (partition (<x) xs)
7+ qsort (x::xs) | (ys, zs) = qsort ys ++ [x] ++ qsort zs
8+
9+total
10+qsort' : Ord a => List a -> List a
11+qsort' [] = []
12+qsort' (x::xs) with (partition (<x) xs)
13+ qsort' (x::xs) | (ys, zs) = ?qsortLemma
14+
15+---------- Proofs ----------
16+
17+qsortLemma = proof
18+ intros
19+ let ys' = qsort' ys
20+ let zs' = qsort' zs
21+ let ws = ys' ++ [x] ++ zs'
22+ trivial
23+
24+
25+
test/reg028/runnew file+4
@@ -0,0 +1,4 @@
1+#!/usr/bin/env bash
2+idris $@ reg028.idr --check
3+idris $@ reg028a.idr --check
4+rm -f *.ibc
test/test001/test001.idr+1−1
@@ -38,7 +38,7 @@ using (G : Vect n Ty)
38 index_first = stop
38 index_first = stop
39 index_next = pop
39 index_next = pop
40
40
41− interp : Env G -> {static} Expr G t -> interpTy t
41+ interp : Env G -> [static] (e : Expr G t) -> interpTy t
42 interp env (Var i) = lookup i env
42 interp env (Var i) = lookup i env
43 interp env (Val x) = x
43 interp env (Val x) = x
44 interp env (Lam sc) = \x => interp (x :: env) sc
44 interp env (Lam sc) = \x => interp (x :: env) sc
test/test003/expected+3−3
@@ -1,7 +1,7 @@
1./test003a.lidr:1:0:Program line next to comment
1./test003a.lidr:1:0:Program line next to comment
2−a
2+'a'
3−d
3+'d'
4zabcdefg
4zabcdefg
5gfedcba
5gfedcba
6−[g, f, e, d, c, b, a]
6+['g', 'f', 'e', 'd', 'c', 'b', 'a']
7abcdefg
7abcdefg
test/test005/expected+2−2
@@ -1,6 +1,6 @@
18
18
21
21
3−(abc, 123)
3+("abc", "123")
4−(abc, 123)
4+("abc", "123")
5([1, 2], [3, 4, 5])
5([1, 2], [3, 4, 5])
6([1, 2], [3, 4, 5])
6([1, 2], [3, 4, 5])
test/test008/test008.idr+1−1
@@ -18,7 +18,7 @@ ioVals = do { return ("First", "second") }
18
18
19main : IO ()
19main : IO ()
20main = do (a, b) <- ioVals
20main = do (a, b) <- ioVals
21− putStr (show a ++ " and " ++ show b ++ "? ")
21+ putStr (a ++ " and " ++ b ++ "? ")
22 let x = "bar"
22 let x = "bar"
23 putStrLn (show (getVal x 7 testlist))
23 putStrLn (show (getVal x 7 testlist))
24 let ((y, z) :: _) = testlist
24 let ((y, z) :: _) = testlist
test/test011/expected+3−3
@@ -1,5 +1,5 @@
1−foo
1+"foo"
2−Fred
2+"Fred"
3[1, 2, 3]
3[1, 2, 3]
4−[b, a]
4+["b", "a"]
525
525
test/test014/Resimp.idr+1−1
@@ -119,7 +119,7 @@ using (i: Fin n, gam : Vect n Ty, gam' : Vect n Ty, gam'' : Vect n Ty)
119 ioret : a -> IO a
119 ioret : a -> IO a
120 ioret = return
120 ioret = return
121
121
122− interp : Env gam -> {static} Res gam gam' t ->
122+ interp : Env gam -> [static] (e : Res gam gam' t) ->
123 (Env gam' -> interpTy t -> IO u) -> IO u
123 (Env gam' -> interpTy t -> IO u) -> IO u
124
124
125 interp env (Let val scope) k
125 interp env (Let val scope) k
test/test014/test014.idr+1
@@ -64,3 +64,4 @@ readH fn = res (do let x = open fn Reading
64main : IO ()
64main : IO ()
65main = run (readH "test")
65main = run (readH "test")
66
66
67+
test/test017/test017.idr+10−8
@@ -20,14 +20,16 @@ ordElim (Suc o) P mZ mSuc mSup = mSuc o (ordElim o P mZ mSuc mSup)
20ordElim (Sup f) P mZ mSuc mSup =
20ordElim (Sup f) P mZ mSuc mSup =
21 mSup f (\n => ordElim (f n) P mZ mSuc mSup)
21 mSup f (\n => ordElim (f n) P mZ mSuc mSup)
22
22
23+-- For now, not going to support this
24+
23−myplus' : Nat -> Nat -> Nat
25+-- myplus' : Nat -> Nat -> Nat
24−myplus : Nat -> Nat -> Nat
26+-- myplus : Nat -> Nat -> Nat
25−
27+--
26−myplus Z y = y
28+-- myplus Z y = y
27−myplus (S k) y = S (myplus' k y)
29+-- myplus (S k) y = S (myplus' k y)
28−
30+--
29−myplus' Z y = y
31+-- myplus' Z y = y
30−myplus' (S k) y = S (myplus y k)
32+-- myplus' (S k) y = S (myplus y k)
31
33
32mnubBy : (a -> a -> Bool) -> List a -> List a
34mnubBy : (a -> a -> Bool) -> List a -> List a
33mnubBy = nubBy' []
35mnubBy = nubBy' []
test/test020/expected+1−1
@@ -11,4 +11,4 @@ Specifically:
11 List a
11 List a
12
12
13[3, 2, 1]
13[3, 2, 1]
14−Number 42
14+"Number 42"
test/test021/expected+1−3
@@ -1,6 +1,4 @@
1−[HELLO!!!
1+["HELLO!!!\n", "WORLD!!!\n", ""]
2−, WORLD!!!
3−, ]
43
23
515
315
6Answer: 99
4Answer: 99
test/test028/test028.idr+1−1
@@ -2,4 +2,4 @@
2module Main
2module Main
3--
3--
4main : IO ()
4main : IO ()
5−main = print "hello, world!"
5+main = putStrLn "hello, world!"
test/test032/expected+3
@@ -9,3 +9,6 @@ isElem2 x (y :: ys) with (_)
9 isElem2 x (y :: ys) | with_pat = ?isElem2_rhs
9 isElem2 x (y :: ys) | with_pat = ?isElem2_rhs
10 isElem3 x (x :: ys) | (Yes refl) = ?isElem3_rhs_3
10 isElem3 x (x :: ys) | (Yes refl) = ?isElem3_rhs_3
11
11
12+ [] => ?bar_1
13+ (_ :: _) => ?bar_2
14+
test/test032/input+1
@@ -3,3 +3,4 @@
3:ps 21 maprhs
3:ps 21 maprhs
4:mw 25 isElem2
4:mw 25 isElem2
5:cs 30 p
5:cs 30 p
6+:cs 35 xs'
test/test032/test032.idr+3
@@ -30,3 +30,6 @@ isElem3 x (y :: ys) with (decEq x y)
30 isElem3 x (y :: ys) | (Yes p) = ?isElem3_rhs_1
30 isElem3 x (y :: ys) | (Yes p) = ?isElem3_rhs_1
31 isElem3 x (y :: ys) | (No _) = ?isElem3_rhs_2
31 isElem3 x (y :: ys) | (No _) = ?isElem3_rhs_2
32
32
33+foo : List a -> List a
34+foo xs = case xs of
35+ xs' => ?bar
test/test034/expected+1−1
@@ -1,5 +1,5 @@
1prim__floatToStr 0.0
1prim__floatToStr 0.0
2−0.0
2+"0.0"
3prim__strToFloat "0.0"
3prim__strToFloat "0.0"
40.0
40.0
5prim__addFloat 1.0 1.0
5prim__addFloat 1.0 1.0
tutorial/Makefiledeleted−40
@@ -1,40 +0,0 @@
1−PAPER = idris-tutorial
2−
3−all: ${PAPER}.pdf
4−
5−TEXFILES = ${PAPER}.tex content/*.tex
6−
7−DIAGS =
8−
9−SOURCES = ${TEXFILES} ${DIAGS} macros.ltx library.ltx literature.bib
10−
11−DITAA = java -jar ~/Downloads/ditaa.jar
12−
13−${PAPER}.pdf: ${SOURCES}
14− pdflatex ${PAPER}
15− -bibtex ${PAPER}
16− -pdflatex ${PAPER}
17− -pdflatex ${PAPER}
18−
19−${PAPER}.ps: ${PAPER}.dvi
20− dvips -o ${PAPER}.ps ${PAPER}
21−
22−${PAPER}.dvi: $(SOURCES)
23− -latex ${PAPER}
24− -bibtex ${PAPER}
25− -latex ${PAPER}
26− -latex ${PAPER}
27−
28−progress: .PHONY
29− wc -w ${TEXFILES}
30−
31−%.png : %.diag
32− $(DITAA) -o -E $<
33−
34−todropbox: .PHONY
35− cp ${SOURCES} ~/Dropbox/TeX/idris-tutorial
36−
37−fromdropbox: .PHONY
38− cp ~/Dropbox/TeX/idris-tutorial/* .
39−
40−.PHONY:
tutorial/conf.ltxdeleted−17
@@ -1,17 +0,0 @@
1−%% This file contains configurations of used packages
2−
3−\lstset{%
4− basicstyle=\ttfamily,
5− xleftmargin=\parindent,
6− tabsize=2
7−}
8−
9−
10−% Configuration of hyperref (to not use colors):
11−\hypersetup{
12− colorlinks,
13− linkcolor=black,
14− citecolor=black,
15− filecolor=black,
16− urlcolor=black
17−}
tutorial/content/classes.texdeleted−440
@@ -1,440 +0,0 @@
1−\section{Type Classes}
2−\label{sec:classes}
3−
4−We often want to define functions which work across several different data
5−types. For example, we would like arithmetic operators to work on \texttt{Int},
6−\texttt{Integer} and \texttt{Float} at the very least. We would like
7−\texttt{==} to work on the majority of data types. We would like to be able to
8−display different types in a uniform way.
9−
10−To achieve this, we use a feature which has proved to be effective in Haskell, namely
11−\emph{type classes}. To define a type class, we provide a collection of overloaded
12−operations which describe the interface for \emph{instances} of that class. A simple example
13−is the \texttt{Show} type class, which is defined in the prelude and
14−provides an interface for converting values to
15−\texttt{String}s:
16−
17−\begin{code}
18−class Show a where
19− show : a -> String
20−\end{code}
21−
22−\noindent
23−This generates a function of the following type (which we call a \emph{method} of the
24−\texttt{Show} class):
25−
26−\begin{code}
27−show : Show a => a -> String
28−\end{code}
29−
30−\noindent
31−We can read this as ``under the constraint that \texttt{a} is an instance of \texttt{Show},
32−take an \texttt{a} as input and return a \texttt{String}.'' An instance of a class
33−is defined with an \texttt{instance} declaration, which provides implementations of
34−the function for a specific type. For example, the \texttt{Show} instance for \texttt{Nat}
35−could be defined as:
36−
37−\begin{code}
38−instance Show Nat where
39− show Z = "Z"
40− show (S k) = "s" ++ show k
41−\end{code}
42−
43−\begin{lstlisting}
44−Idris> show (S (S (S Z)))
45−"sssO" : String
46−\end{lstlisting}
47−
48−\noindent
49−Only one instance of a class can be given for a type --- instances may not overlap.
50−Instance declarations can themselves have constraints. For example, to define a
51−\texttt{Show} instance for vectors, we need to know that there is a \texttt{Show}
52−instance for the element type, because we are going to use it to convert each element
53−to a \texttt{String}:
54−
55−\begin{code}
56−instance Show a => Show (Vect n a) where
57− show xs = "[" ++ show' xs ++ "]" where
58− show' : Vect n a -> String
59− show' Nil = ""
60− show' (x :: Nil) = show x
61− show' (x :: xs) = show x ++ ", " ++ show' xs
62−\end{code}
63−
64−%\noindent
65−%\textbf{Remark: } The type of the auxiliary function \texttt{show'} is
66−%important. The type variables \texttt{a} and \texttt{n} which are part of the
67−%instance declaration for \texttt{Show (Vect a n)} are fixed across the entire
68−%instance declaration. As a result, we do not have to constrain \texttt{a}
69−%again. Furthermore, it means that if we use \texttt{n} in the type, it refers
70−%to the (fixed) length of the outermost list \texttt{xs}. Therefore,
71−%we use a different name for the length \texttt{n'} in \texttt{show'}.
72−
73−\subsection{Default Definitions}
74−
75−The library defines an \texttt{Eq} class which provides an interface for comparing
76−values for equality or inequality, with instances for all of the built-in types:
77−
78−\begin{code}
79−class Eq a where
80− (==) : a -> a -> Bool
81− (/=) : a -> a -> Bool
82−\end{code}
83−
84−\noindent
85−To declare an instance of a type, we have to give definitions of all of the methods.
86−For example, for an instance of \texttt{Eq} for \texttt{Nat}:
87−
88−\begin{code}
89−instance Eq Nat where
90− Z == Z = True
91− (S x) == (S y) = x == y
92− Z == (S y) = False
93− (S x) == Z = False
94−
95− x /= y = not (x == y)
96−\end{code}
97−
98−\noindent
99−It is hard to imagine many cases where the \texttt{/=} method will be anything other
100−than the negation of the result of applying the \texttt{==} method. It is therefore
101−convenient to give a default definition for each method in the class
102−declaration, in terms of the other method:
103−
104−\begin{code}
105−class Eq a where
106− (==) : a -> a -> Bool
107− (/=) : a -> a -> Bool
108−
109− x /= y = not (x == y)
110− y == y = not (x /= y)
111−\end{code}
112−
113−\noindent
114−A minimal complete definition of an \texttt{Eq} instance requires either \texttt{==}
115−or \texttt{/=} to be defined, but does not require both. If a method definition is
116−missing, and there is a default definition for it, then the default is used instead.
117−
118−\subsection{Extending Classes}
119−
120−Classes can also be extended. A logical next step from an equality relation \texttt{Eq}
121−is to define an ordering relation \texttt{Ord}. We can define an \texttt{Ord} class
122−which inherits methods from \texttt{Eq} as well as defining some of its own:
123−
124−\begin{code}
125−data Ordering = LT | EQ | GT
126−\end{code}
127−
128−\begin{code}
129−class Eq a => Ord a where
130− compare : a -> a -> Ordering
131−
132− (<) : a -> a -> Bool
133− (>) : a -> a -> Bool
134− (<=) : a -> a -> Bool
135− (>=) : a -> a -> Bool
136− max : a -> a -> a
137− min : a -> a -> a
138−\end{code}
139−
140−\noindent
141−The \texttt{Ord} class allows us to compare two values and determine their ordering.
142−Only the \texttt{compare} method is required; every other method has a default definition.
143−Using
144−this we can write functions such as \texttt{sort}, a function which sorts a list into
145−increasing order, provided that the element type of the list is in the \texttt{Ord} class.
146−We give the constraints on the type variables left of the fat arrow \texttt{=>}, and the
147−function type to the right of the fat arrow:
148−
149−\begin{code}
150−sort : Ord a => List a -> List a
151−\end{code}
152−
153−\noindent
154−Functions, classes and instances can have multiple constraints. Multiple constaints are
155−written in brackets in a comma separated list, for example:
156−
157−\begin{code}
158−sortAndShow : (Ord a, Show a) => List a -> String
159−sortAndShow xs = show (sort xs)
160−\end{code}
161−
162−\subsection{Monads and \texttt{do}-notation}
163−
164−\label{sec:monad}
165−
166−So far, we have seen single parameter type classes, where the parameter is of type
167−\texttt{Type}. In general, there can be any number (greater than 0) of parameters,
168−and the parameters can have \remph{any} type.
169−If the type of the parameter is not \texttt{Type}, we need to give an explicit type
170−declaration. For example:
171−
172−\begin{code}
173−class Monad (m : Type -> Type) where
174− return : a -> m a
175− (>>=) : m a -> (a -> m b) -> m b
176−\end{code}
177−
178−\noindent
179−The \texttt{Monad} class allows us to encapsulate binding and computation, and is the
180−basis of \texttt{do}-notation introduced in Section \ref{sect:do}. Inside a
181−\texttt{do} block, the following syntactic transformations are applied:
182−
183−\begin{itemize}
184−\item \texttt{x <- v; e} becomes \texttt{v >>= ($\backslash$x => e)}
185−\item \texttt{v; e} becomes \texttt{v >>= ($\backslash$\_ => e)}
186−\item \texttt{let x = v; e} becomes \texttt{let x = v in e}
187−\end{itemize}
188−
189−\noindent
190−\texttt{IO} is an instance of \texttt{Monad}, defined using primitive functions.
191−We can also define an instance for \texttt{Maybe}, as follows:
192−
193−\begin{code}
194−instance Monad Maybe where
195− return = Just
196−
197− Nothing >>= k = Nothing
198− (Just x) >>= k = k x
199−\end{code}
200−
201−\noindent
202−Using this we can, for example, define a function which adds two
203−\texttt{Maybe Int}s, using the monad to encapsulate the error handling:
204−
205−\begin{code}
206−m_add : Maybe Int -> Maybe Int -> Maybe Int
207−m_add x y = do x' <- x -- Extract value from x
208− y' <- y -- Extract value from y
209− return (x' + y') -- Add them
210−\end{code}
211−
212−\noindent
213−This function will extract the values from \texttt{x} and \texttt{y}, if they
214−are available, or return \texttt{Nothing} if they are not. Managing the
215−\texttt{Nothing} cases is achieved by the \texttt{>>=} operator, hidden by the
216−\texttt{do} notation.
217−
218−\begin{lstlisting}
219−*classes> m_add (Just 20) (Just 22)
220−Just 42 : Maybe Int
221−*classes> m_add (Just 20) Nothing
222−Nothing : Maybe Int
223−\end{lstlisting}
224−
225−\subsubsection*{Monad comprehensions}
226−
227−The list comprehension notation we saw in Section \ref{sec:listcomp} is more
228−general, and applies to anything which is an instance of \texttt{MonadPlus}:
229−
230−\begin{code}
231−class Monad m => MonadPlus (m : Type -> Type) where
232− mplus : m a -> m a -> m a
233− mzero : m a
234−\end{code}
235−
236−\noindent
237−In general, a comprehension takes the form \texttt{[ exp | qual1, qual2, ..., qualn ]} where
238−\texttt{quali} can be one of:
239−
240−\begin{itemize}
241−\item A generator \texttt{x <- e}
242−\item A \emph{guard}, which is an expression of type \texttt{Bool}
243−\item A let binding \texttt{let x = e}
244−\end{itemize}
245−
246−\noindent
247−To translate a comprehension \texttt{[exp | qual1, qual2, ..., qualn]}, first
248−any qualifier
249−\texttt{qual} which is a \emph{guard} is translated to \texttt{guard qual}, using
250−the following function:
251−
252−\begin{code}
253−guard : MonadPlus m => Bool -> m ()
254−\end{code}
255−
256−\noindent
257−Then the comprehension is converted to \texttt{do} notation:
258−
259−\begin{code}
260−do { qual1; qual2; ...; qualn; return exp; }
261−\end{code}
262−
263−\noindent
264−Using monad comprehensions, an alternative definition for \texttt{m\_add} would be:
265−
266−\begin{code}
267−m_add : Maybe Int -> Maybe Int -> Maybe Int
268−m_add x y = [ x' + y' | x' <- x, y' <- y ]
269−\end{code}
270−
271−\subsection{Idiom brackets}
272−
273−While \texttt{do} notation gives an alternative meaning to sequencing, idioms give an
274−alternative meaning to \emph{application}. The notation and larger example in this
275−section is inspired by Conor McBride and Ross Paterson's paper "Applicative
276−Programming with Effects"~\cite{idioms}.
277−
278−First, let us revisit \texttt{m\_add} above. All it is really doing is applying
279−an operator to two values extracted from Maybe Ints. We could abstract out the
280−application:
281−
282−\begin{code}
283−m_app : Maybe (a -> b) -> Maybe a -> Maybe b
284−m_app (Just f) (Just a) = Just (f a)
285−m_app _ _ = Nothing
286−\end{code}
287−
288−\noindent
289−Using this, we can write an alternative \texttt{m\_add} which uses this alternative
290−notion of function application, with explicit calls to \texttt{m\_app}:
291−
292−\begin{code}
293−m_add' : Maybe Int -> Maybe Int -> Maybe Int
294−m_add' x y = m_app (m_app (Just (+)) x) y
295−\end{code}
296−
297−\noindent
298−Rather than having to insert \texttt{m\_app} everywhere there is an
299−application, we can use \remph{idiom brackets} to do the job for us. To do
300−this, we use the \texttt{Applicative} class, which captures the notion of
301−application for a data type:
302−
303−\begin{code}
304−infixl 2 <$>
305−
306−class Applicative (f : Type -> Type) where
307− pure : a -> f a
308− (<$>) : f (a -> b) -> f a -> f b
309−\end{code}
310−
311−\noindent
312−\texttt{Maybe} is made an instance of \texttt{Applicative} as follows, where
313−\texttt{<\$>} is defined in the same way as \texttt{m\_app} above:
314−
315−\begin{code}
316−instance Applicative Maybe where
317− pure = Just
318−
319− (Just f) <$> (Just a) = Just (f a)
320− _ <$> _ = Nothing
321−\end{code}
322−
323−\noindent
324−Using \remph{idiom brackets} we can use this instance as follows, where a function
325−application \texttt{[| f a1 ... an |]}
326−is translated into \texttt{pure f <\$> a1 <\$> ... <\$> an}:
327−
328−\begin{code}
329−m_add' : Maybe Int -> Maybe Int -> Maybe Int
330−m_add' x y = [| x + y |]
331−\end{code}
332−
333−\subsubsection{An error-handling interpreter}
334−
335−Idiom notation is commonly useful when defining evaluators. McBride and
336−Paterson describe such an evaluator~\cite{idioms}, for a language similar to
337−the following:
338−
339−\begin{code}
340−data Expr = Var String -- variables
341− | Val Int -- values
342− | Add Expr Expr -- addition
343−\end{code}
344−
345−\noindent
346−Evaluation will take place relative to a context mapping variables (represented as
347−\texttt{String}s) to integer values, and can possibly fail. We define a data type
348−\texttt{Eval} to wrap an evaluator:
349−
350−\begin{code}
351−data Eval : Type -> Type where
352− MkEval : (List (String, Int) -> Maybe a) -> Eval a
353−\end{code}
354−
355−\noindent
356−Wrapping the evaluator in a data type means we will be able to make it an instance
357−of a type class later. We begin by defining a function to retrieve values from
358−the context during evaluation:
359−
360−\begin{code}
361−fetch : String -> Eval Int
362−fetch x = MkEval (\e => fetchVal e) where
363− fetchVal : List (String, Int) -> Maybe Int
364− fetchVal [] = Nothing
365− fetchVal ((v, val) :: xs) = if (x == v) then (Just val) else (fetchVal xs)
366−\end{code}
367−
368−\noindent
369−When defining an evaluator for the language, we will be applying functions in
370−the context of an \texttt{Eval}, so it is natural to make \texttt{Eval} an
371−instance of \texttt{Applicative}.
372−Before \texttt{Eval} can be an instance of
373−\texttt{Applicative} it is necessary to make \texttt{Eval} an instance of
374−\texttt{Functor}:
375−
376−\begin{code}
377−instance Functor Eval where
378− fmap f (MkEval g) = MkEval (\e => fmap f (g e))
379−
380−instance Applicative Eval where
381− pure x = MkEval (\e => Just x)
382−
383− (<$>) (MkEval f) (MkEval g) = MkEval (\x => app (f x) (g x)) where
384− app : Maybe (a -> b) -> Maybe a -> Maybe b
385− app (Just fx) (Just gx) = Just (fx gx)
386− app _ _ = Nothing
387−\end{code}
388−
389−\noindent
390−Evaluating an expression can now make use of the idiomatic application to handle
391−errors:
392−
393−\begin{code}
394−eval : Expr -> Eval Int
395−eval (Var x) = fetch x
396−eval (Val x) = [| x |]
397−eval (Add x y) = [| eval x + eval y |]
398−
399−runEval : List (String, Int) -> Expr -> Maybe Int
400−runEval env e = case eval e of
401− MkEval envFn => envFn env
402−\end{code}
403−
404−\subsection{Named Instances}
405−
406−It can be desirable to have multiple instances of a type class, for example to provide
407−alternative methods for sorting or printing values. To achieve this, instances can
408−be \remph{named} as follows:
409−
410−\begin{code}
411−instance [myord] Ord Nat where
412− compare Z (S n) = GT
413− compare (S n) Z = LT
414− compare Z Z = EQ
415− compare (S x) (S y) = compare @{myord} x y
416−\end{code}
417−
418−\noindent
419−This declares an instance as normal, but with an explicit name, \texttt{myord}.
420−The syntax \texttt{compare @\{myord\}} gives an explicit instance to
421−\texttt{compare}, otherwise it would use the default instance for \texttt{Nat}.
422−We can use this, for example, to sort a list of \texttt{Nat}s in reverse.
423−Given the following list:
424−
425−\begin{code}
426−testList : List Nat
427−testList = [3,4,1]
428−\end{code}
429−
430−\noindent
431−\ldots we can sort it using the default \texttt{Ord} instance, then the named
432−instance \texttt{myord} as follows, at the \Idris{} prompt:
433−
434−\begin{lstlisting}
435−*named_instance> show (sort testList)
436−"[sO, sssO, ssssO]" : String
437−*named_instance> show (sort @{myord} testList)
438−"[ssssO, sssO, sO]" : String
439−\end{lstlisting}
440−
tutorial/content/conclusions.texdeleted−14
@@ -1,14 +0,0 @@
1−\section{Further Reading}
2−
3−Further information about \Idris{} programming, and programming with dependent
4−types in general, can be obtained from various sources:
5−
6−\begin{itemize}
7−\item The \Idris{} web site (\url{http://idris-lang.org/}) and by asking questions
8−on the mailing list.
9−\item The IRC channel \texttt{\#idris}, on \url{chat.freenode.net}.
10−\item Examining the prelude and exploring the \texttt{samples} in the distribution.
11−\item Various papers (e.g. \cite{plpv11, scrap-engine,res-dsl-padl12}). These mostly describe
12−older versions of \Idris{}.
13−\end{itemize}
14−
tutorial/content/dsl.texdeleted−82
@@ -1,82 +0,0 @@
1−\subsection{\texttt{dsl} notation}
2−
3−The well-typed interpreter in Section \ref{sect:interp} is a simple example of
4−a common programming pattern with dependent types, namely: describe an
5−\emph{object language}
6−and its type system with dependent types to guarantee that only well-typed programs
7−can be represented, then program using that representation. Using this approach
8−we can, for example, write programs for serialising binary data~\cite{plpv11} or
9−running concurrent processes safely~\cite{cbconc-fi}.
10−
11−Unfortunately, the form of object language programs makes it rather hard to program
12−this way in practice. Recall the factorial program in \texttt{Expr} for example:
13−
14−\begin{code}
15−fact : Expr G (TyFun TyInt TyInt)
16−fact = Lam (If (Op (==) (Var stop) (Val 0))
17− (Val 1) (Op (*) (app fact (Op (-) (Var stop) (Val 1)))
18− (Var stop)))
19−\end{code}
20−
21−\noindent
22−Since this is a particularly useful pattern, \Idris{} provides syntax
23−overloading~\cite{res-dsl-padl12} to make it easier to program in such
24−object languages:
25−
26−\begin{code}
27−dsl expr
28− lambda = Lam
29− variable = Var
30− index_first = stop
31− index_next = pop
32−\end{code}
33−
34−\noindent
35−A \texttt{dsl} block describes how each syntactic construct is represented in an
36−object language. Here, in the \texttt{expr} language, any \Idris{} lambda is
37−translated to a \texttt{Lam} constructor; any variable is translated to the
38−\texttt{Var} constructor, using \texttt{pop} and \texttt{stop} to construct the
39−de Bruijn index (i.e., to count how many bindings since the variable itself was bound).
40−It is also possible to overload \texttt{let} in this way. We can now write \texttt{fact}
41−as follows:
42−
43−\begin{code}
44−fact : Expr G (TyFun TyInt TyInt)
45−fact = expr (\x => If (Op (==) x (Val 0))
46− (Val 1) (Op (*) (app fact (Op (-) x (Val 1))) x))
47−\end{code}
48−
49−\noindent
50−In this new version, \texttt{expr} declares that the next expression will be overloaded.
51−We can take this further, using idiom brackets, by declaring:
52−
53−\begin{code}
54−(<$>) : |(f : Expr G (TyFun a t)) -> Expr G a -> Expr G t
55−(<$>) = \f, a => App f a
56−
57−pure : Expr G a -> Expr G a
58−pure = id
59−\end{code}
60−
61−\noindent
62−Note that there is no need for these to be part of an instance of \texttt{Applicative},
63−since idiom bracket notation translates directly to the names \texttt{<\$>} and
64−\texttt{pure}, and ad-hoc type-directed overloading is allowed. We can now say:
65−
66−\begin{code}
67−fact : Expr G (TyFun TyInt TyInt)
68−fact = expr (\x => If (Op (==) x (Val 0))
69− (Val 1) (Op (*) [| fact (Op (-) x (Val 1)) |] x))
70−\end{code}
71−
72−\noindent
73−With some more ad-hoc overloading and type class instances, and a new
74−syntax rule, we can even go as far as:
75−
76−\begin{code}
77−syntax IF [x] THEN [t] ELSE [e] = If x t e
78−
79−fact : Expr G (TyFun TyInt TyInt)
80−fact = expr (\x => IF x == 0 THEN 1 ELSE [| fact (x - 1) |] * x)
81−\end{code}
82−
tutorial/content/interp.texdeleted−332
@@ -1,332 +0,0 @@
1−\section{Example: The Well-Typed Interpreter}
2−\label{sect:interp}
3−
4−In this section, we'll use the features we've seen so far to write a larger
5−example, an interpreter for a simple functional programming language, with
6−variables, function application, binary operators and an \texttt{if...then...else}
7−construct. We will use the dependent type system to ensure that any programs
8−which can be represented are well-typed. First, let us define the types in the
9−language. We have integers, booleans, and functions, represented by \texttt{Ty}:
10−
11−\begin{code}
12−data Ty = TyInt | TyBool | TyFun Ty Ty
13−\end{code}
14−
15−\noindent
16−We can write a function to translate these representations to a concrete \Idris{}
17−type --- remember that types are first class, so can be calculated just like
18−any other value:
19−
20−\begin{code}
21−interpTy : Ty -> Type
22−interpTy TyInt = Int
23−interpTy TyBool = Bool
24−interpTy (TyFun A T) = interpTy A -> interpTy T
25−\end{code}
26−
27−\noindent
28−We're going to define a representation of our language in such a way that only
29−well-typed programs can be represented. We'll index the representations of
30−expressions by their type and the types of local variables (the context), which
31−we'll be using regularly as an implicit argument, so we define everything
32−in a \texttt{using} block:
33−
34−\begin{code}
35−using (G:Vect n Ty)
36−\end{code}
37−
38−\noindent
39−The full representation of expressions is given in Figure \ref{exprty}. They are
40−indexed by the types of the local variables, and the type of the expression itself:
41−
42−\begin{code}
43−data Expr : Vect n Ty -> Ty -> Type
44−\end{code}
45−
46−\noindent
47−Since expressions are indexed by their type, we can read the typing rules of
48−the language from the definitions of the constructors. Let us look at each
49−constructor in turn.
50−
51−\begin{code}[caption={Expression representation},label=exprty]
52−data HasType : (i : Fin n) -> Vect n Ty -> Ty -> Type where
53− stop : HasType fZ (t :: G) t
54− pop : HasType k G t -> HasType (fS k) (u :: G) t
55−
56−data Expr : Vect n Ty -> Ty -> Type where
57− Var : HasType i G t -> Expr G t
58− Val : (x : Int) -> Expr G TyInt
59− Lam : Expr (a :: G) t -> Expr G (TyFun a t)
60− App : Expr G (TyFun a t) -> Expr G a -> Expr G t
61− Op : (interpTy a -> interpTy b -> interpTy c) -> Expr G a -> Expr G b ->
62− Expr G c
63− If : Expr G TyBool -> Expr G a -> Expr G a -> Expr G a
64−\end{code}
65−
66−\noindent
67−We use a nameless representation for variables --- they are \emph{de Bruijn indexed}.
68−Variables are represented by a proof of their membership in the context,
69−\texttt{HasType i G T}, which is a proof that variable \texttt{i} in context
70−\texttt{G} has type \texttt{T}. This is defined as follows:
71−
72−\begin{code}
73−data HasType : (i : Fin n) -> Vect n Ty -> Ty -> Type where
74− stop : HasType fZ (t :: G) t
75− pop : HasType k G t -> HasType (fS k) (u :: G) t
76−\end{code}
77−
78−\noindent
79−We can treat \remph{stop} as a proof that the most recently defined variable is well-typed,
80−and \remph{pop n} as a proof that, if the \texttt{n}th most recently defined variable is
81−well-typed, so is the \texttt{n+1}th. In practice, this means we use \texttt{stop} to
82−refer to the most recently defined variable, \texttt{pop stop} to refer to the next, and so on,
83−via the \texttt{Var} constructor:
84−
85−\begin{code}
86−Var : HasType i G t -> Expr G t
87−\end{code}
88−
89−\noindent
90−So, in an expression \texttt{$\backslash$x. $\backslash$y. x y},
91−the variable \texttt{x} would have a de Bruijn index
92−of 1, represented as \texttt{pop stop}, and \texttt{y 0}, represented
93−as \texttt{stop}. We find these by counting the number of lambdas between the
94−definition and the use.
95−
96−\noindent
97−A value carries a concrete representation of an integer:
98−
99−\begin{code}
100−Val : (x : Int) -> Expr G TyInt
101−\end{code}
102−
103−\noindent
104−A lambda creates a function. In the scope of a function of type \texttt{a -> t}, there is
105−a new local variable of type \texttt{a}, which is expressed by the context index:
106−
107−\begin{code}
108−Lam : Expr (a :: G) t -> Expr G (TyFun a t)
109−\end{code}
110−
111−\noindent
112−Function application produces a value of type \texttt{t} given a function from
113−\texttt{a} to \texttt{t}
114−and a value of type \texttt{a}:
115−
116−\begin{code}
117−App : Expr G (TyFun a t) -> Expr G a -> Expr G t
118−\end{code}
119−
120−\noindent
121−We allow arbitrary binary operators, where the type of the operator
122−informs what the types of the arguments must be:
123−
124−\begin{code}
125−Op : (interpTy a -> interpTy b -> interpTy c) -> Expr G a -> Expr G b ->
126− Expr G c
127−\end{code}
128−
129−\noindent
130−Finally, if expressions make a choice given a boolean. Each branch must
131−have the same type:
132−
133−\begin{code}
134−If : Expr G TyBool -> Expr G a -> Expr G a -> Expr G a
135−\end{code}
136−
137−\noindent
138−When we evaluate an \texttt{Expr}, we'll need to know the values in scope, as well as
139−their types. \texttt{Env} is an environment, indexed over the types in scope.
140−Since an environment is just another form of list, albeit with a strongly specified connection
141−to the vector of local variable types, we use the usual \texttt{::} and \texttt{Nil}
142−constructors so that we can use the usual list syntax. Given a proof that a variable
143−is defined in the context, we can then produce a value from the environment:
144−
145−\begin{code}
146−data Env : Vect n Ty -> Type where
147− Nil : Env Nil
148− (::) : interpTy a -> Env G -> Env (a :: G)
149−
150−lookup : HasType i G t -> Env G -> interpTy t
151−lookup stop (x :: xs) = x
152−lookup (pop k) (x :: xs) = lookup k xs
153−\end{code}
154−
155−\begin{code}[caption={Intepreter definition},label=interpdef]
156−interp : Env G -> Expr G t -> interpTy t
157−interp env (Var i) = lookup i env
158−interp env (Val x) = x
159−interp env (Lam sc) = \x => interp (x :: env) sc
160−interp env (App f s) = interp env f (interp env s)
161−interp env (Op op x y) = op (interp env x) (interp env y)
162−interp env (If x t e) = if interp env x then interp env t
163− else interp env e
164−\end{code}
165−
166−\noindent
167−Given this, an interpreter (Figure \ref{interpdef})
168−is a function which translates an \texttt{Expr} into a
169−concrete \Idris{} value with respect to a specific environment:
170−
171−\begin{code}
172−interp : Env G -> Expr G t -> interpTy t
173−\end{code}
174−
175−\noindent
176−To translate a variable, we simply look it up in the environment:
177−
178−\begin{code}
179−interp env (Var i) = lookup i env
180−\end{code}
181−
182−\noindent
183−To translate a value, we just return the concrete representation of the value:
184−
185−\begin{code}
186−interp env (Val x) = x
187−\end{code}
188−
189−\noindent
190−Lambdas are more interesting. In this case, we construct a function which
191−interprets the scope of the lambda with a new value in the environment. So, a
192−function in the object language is translated to an \Idris{} function:
193−
194−\begin{code}
195−interp env (Lam sc) = \x => interp (x :: env) sc
196−\end{code}
197−
198−\noindent
199−For an application, we interpret the function and its argument and apply it
200−directly. We know that interpreting \texttt{f} must produce a function, because of its
201−type:
202−
203−\begin{code}
204−interp env (App f s) = interp env f (interp env s)
205−\end{code}
206−
207−\noindent
208−Operators and interpreters are, again, direct translations into the equivalent
209−\Idris{} constructs. For operators, we apply the function to its operands directly,
210−and for \texttt{If}, we apply the \Idris{} \texttt{if...then...else} construct
211−directly.
212−
213−\begin{code}
214−interp env (Op op x y) = op (interp env x) (interp env y)
215−interp env (If x t e) = if interp env x then interp env t
216− else interp env e
217−\end{code}
218−
219−\noindent
220−We can make some simple test functions. Firstly, adding two inputs
221−\texttt{$\backslash$x. $\backslash$y. y + x} is written as follows:
222−
223−\begin{code}
224−add : Expr G (TyFun TyInt (TyFun TyInt TyInt))
225−add = Lam (Lam (Op (+) (Var stop) (Var (pop stop))))
226−\end{code}
227−
228−\noindent
229−More interestingly, we can write a factorial function. First, we write a \emph{lazy}
230−version of the \texttt{App} constructor, so that the recursive branch will only
231−be evaluated if necessary:
232−
233−\begin{code}
234−app : |(f : Expr G (TyFun a t)) -> Expr G a -> Expr G t
235−app = \f, a => App f a
236−\end{code}
237−
238−\noindent
239−The vertical bar annotation before the \texttt{f} argument indicates that this
240−argument should be evaluated lazily when \texttt{app} is applied --- that is, the
241−argument will be evaluated only when needed.
242−Then \texttt{fact}
243−(i.e. \texttt{$\backslash$x. if (x == 0) then 1 else (fact (x-1) * x)})
244−is written as follows:
245−
246−\begin{code}
247−fact : Expr G (TyFun TyInt TyInt)
248−fact = Lam (If (Op (==) (Var stop) (Val 0))
249− (Val 1) (Op (*) (app fact (Op (-) (Var stop) (Val 1)))
250− (Var stop)))
251−\end{code}
252−
253−To finish, we write a \texttt{main} program which interprets the factorial function
254−on user input:
255−
256−\begin{code}
257−main : IO ()
258−main = do putStr "Enter a number: "
259− x <- getLine
260− print (interp [] fact (cast x))
261−\end{code}
262−
263−\noindent
264−Here, \texttt{cast} is an overloaded function which converts a value from one
265−type to another if possible. Here, it converts a string to
266−an integer, giving 0 if the input is invalid. An example run of this program
267−at the \Idris{} interactive environment is shown in Figure \ref{factrun}.
268−
269−\begin{lstlisting}[caption={Running the well-typed interpreter}, label=factrun, escapechar=^]
270−$ idris interp.idr
271− ____ __ _
272− / _/___/ /____(_)____
273− / // __ / ___/ / ___/ Version ^\version{}^
274− _/ // /_/ / / / (__ ) http://www.idris-lang.org/
275− /___/\__,_/_/ /_/____/ Type :? for help
276−
277−Type checking ./interp.idr
278−*interp> :exec
279−Enter a number: 6
280−720
281−*interp>
282−\end{lstlisting}
283−
284−\subsubsection*{Aside: \texttt{cast}}
285−
286−The prelude defines a type class \texttt{Cast} which allows conversion between
287−types:
288−
289−\begin{code}
290−class Cast from to where
291− cast : from -> to
292−\end{code}
293−
294−\noindent
295−It is a \emph{multi-parameter} type class, defining the source type and object
296−type of the cast. It must be possible for the type checker to infer \remph{both}
297−parameters at the point where the cast is applied.
298−There are casts defined between all of the primitive types, as far as
299−they make sense.
300−
301−\subsection{Unit testing}
302−
303−Recall the \texttt{so} data type:
304−
305−\begin{code}
306−data so : Bool -> Type where
307− oh : so True
308−\end{code}
309−
310−\noindent
311−This requires its parameter to be a \texttt{True} value. One simple application of this
312−is to perform unit testing of functions at compile time. For example, we know that
313−\texttt{4! = 24} so we can set up a test case as follows:
314−
315−\begin{code}
316−unitTestFac : so (interp [] fact 4 == 24)
317−unitTestFac = oh
318−\end{code}
319−
320−\noindent
321−For the program to compile, the test case must pass. If we change \texttt{24} to \texttt{25},
322−say, we will get an error message like the following:
323−
324−\begin{lstlisting}
325−Type checking ./interp.idr
326−interp.idr:64:Can't unify so True with so False
327−
328−Specifically:
329− Can't unify True with False
330−\end{lstlisting}
331−
332−
tutorial/content/intro.texdeleted−65
@@ -1,65 +0,0 @@
1−\section{Introduction}
2−
3−In conventional programming languages, there is a clear distinction between
4−\remph{types} and \remph{values}. For example, in Haskell~\cite{haskell-report},
5−the following are types, representing integers, characters, lists of characters,
6−and lists of any value respectively:
7−
8−\begin{itemize}
9−\item \texttt{Int}, \texttt{Char}, \texttt{[Char]}, \texttt{[a]}
10−\end{itemize}
11−
12−\noindent
13−Correspondingly, the following values are examples of inhabitants of those types:
14−
15−\begin{itemize}
16−\item \texttt{42}, \texttt{'a'}, \texttt{"Hello world!"}, \texttt{[2,3,4,5,6]}
17−\end{itemize}
18−
19−\noindent
20−In a language with \emph{dependent types}, however, the distinction is less
21−clear.
22−Dependent types allow types to ``depend'' on values --- in other words,
23−types are a \emph{first class} language construct and can be manipulated like
24−any other value. The standard
25−example is the type of lists of a given length\footnote{Typically, and perhaps
26−confusingly, referred to in the dependently typed programming literature as
27−``vectors''}, \texttt{Vect n a}, where \texttt{a} is the element type and
28−\texttt{n} is the length of the list and can be an arbitrary
29−term.
30−
31−When types can contain values, and where those values describe properties (e.g.
32−the length of a list)
33−the type of a function can begin to describe its own properties. For example,
34−concatenating two lists has the property that the resulting list's length is
35−the sum of the lengths of the two input lists. We can therefore give the following type
36−to the \texttt{app} function, which concatenates vectors:
37−
38−\begin{lstlisting}
39−app : Vect n a -> Vect m a -> Vect (n + m) a
40−\end{lstlisting}
41−
42−\noindent
43−This tutorial introduces \Idris{}, a general purpose functional
44−programming language with dependent types.
45−The goal of the \Idris{} project is to build a dependently typed language suitable
46−for verifiable \emph{systems} programming. To this end, \Idris{} is a compiled language
47−which aims to generate efficient executable code. It also has a lightweight foreign
48−function interface which allows easy interaction with external C libraries.
49−
50−\subsection{Intended Audience}
51−
52−This tutorial is intended as a brief introduction to the language, and is aimed
53−at readers already familiar with a functional language such as Haskell or
54−OCaml. In particular, a certain amount of familiarity with Haskell syntax is
55−assumed, although most concepts will at least be explained briefly. The reader
56−is also assumed to have some interest in using dependent types for writing and
57−verifying systems software.
58−
59−\subsection{Example Code}
60−
61−This tutorial includes some example code, which has been tested with \Idris{} version
62−\version{}. The files are available in the \Idris{} distribution,
63−so that you can try them out easily,
64−under \texttt{tutorial/examples}. However, it is strongly recommended that you
65−type them in yourself, rather than simply loading and reading them.
tutorial/content/miscellany.texdeleted−458
@@ -1,458 +0,0 @@
1−\section{Miscellany}
2−
3−In this section we discuss a variety of additional features:
4−auto implicit and default
5−arguments, literate programming, interfacing with external libraries through the
6−foreign function interface, type providers, code generation and the universe hierarchy.
7−
8−\subsection{Auto implicit arguments}
9−
10−We have already seen implicit arguments, which allows arguments to be omitted when
11−they can be inferred by the type checker, e.g.
12−
13−\begin{code}
14−index : {a:Type} -> {n:Nat} -> Fin n -> Vect n a -> a
15−\end{code}
16−
17−\noindent
18−In other situations, it may be possible to infer arguments not by type checking but
19−by searching the context for an appropriate value, or constructing a proof. For example,
20−the following definition of \texttt{head} which requires a proof that the list is
21−non-empty
22−
23−\begin{code}
24−isCons : List a -> Bool
25−isCons [] = False
26−isCons (x :: xs) = True
27−
28−head : (xs : List a) -> (isCons xs = True) -> a
29−head (x :: xs) _ = x
30−\end{code}
31−
32−\noindent
33−If the list is statically known to be non-empty, either because its value is known or
34−because a proof already exists in the context, the proof can be constructed
35−automatically. Auto implicit arguments allow this to happen silently. We define
36−\texttt{head} as follows:
37−
38−\begin{code}
39−head : (xs : List a) -> {auto p : isCons xs = True} -> a
40−head (x :: xs) = x
41−\end{code}
42−
43−\noindent
44−The \texttt{auto} annotation on the implicit argument means that \Idris{} will
45−attempt to fill in the implicit argument using the \texttt{trivial} tactic, which
46−searches through the context for a proof, and tries to solve with \texttt{refl}
47−if a proof is not found.
48−Now when \texttt{head} is applied, the proof can be omitted. In the case that a proof
49−is not found, it can be provided explicitly as normal:
50−
51−\begin{code}
52−head xs {p = ?headProof}
53−\end{code}
54−
55−\noindent
56−More generally, we can fill in implicit arguments with a default value by annotating
57−them with \texttt{default}. The definition above is equivalent to:
58−
59−\begin{code}
60−head : (xs : List a) ->
61− {default proof { trivial; } p : isCons xs = True} -> a
62−head (x :: xs) = x
63−\end{code}
64−
65−\subsection{Implicit conversions}
66−
67−\Idris{} supports the creation of \emph{implicit conversions}, which allow
68−automatic conversion of values from one type to another when required to make
69−a term type correct. This is intended to increase convenience and reduce
70−verbosity. A contrived but simple example is the following:
71−
72−\begin{code}
73−implicit intString : Int -> String
74−intString = show
75−
76−test : Int -> String
77−test x = "Number " ++ x
78−\end{code}
79−
80−\noindent
81−In general, we cannot append an \texttt{Int} to a \texttt{String}, but the
82−implicit conversion function \texttt{intString} can convert \texttt{x} to a
83−\texttt{String}, so the definition of \texttt{test} is type correct. An
84−implicit conversion is implemented just like any other function, but given
85−the \texttt{implicit} modifier, and restricted to one explicit argument.
86−
87−Only one implicit conversion will be applied at a time. That is, implicit
88−conversions cannot be chained.
89−Implicit conversions of simple types, as above, are however discouraged! More
90−commonly, an implicit conversion would be used to reduce verbosity in an
91−embedded domain specific language, or to hide details of a proof. Such examples
92−are beyond the scope of this tutorial.
93−
94−\subsection{Literate programming}
95−
96−Like Haskell, \Idris{} supports \emph{literate} programming. If a file has an
97−extension of \texttt{.lidr} then it is assumed to be a literate file. In literate
98−programs, everything is assumed to be a comment unless the line begins with a
99−greater than sign \texttt{>}, for example:
100−
101−\begin{lstlisting}
102−> module literate
103−
104−This is a comment. The main program is below
105−
106−> main : IO ()
107−> main = putStrLn "Hello literate world!\n"
108−\end{lstlisting}
109−
110−\noindent
111−An additional restriction is that there must be a blank line between a program
112−line (beginning with \texttt{>}) and a comment line (beginning with any other
113−character).
114−
115−\subsection{Foreign function calls}
116−
117−For practical programming, it is often necessary to be able to use external libraries,
118−particularly for interfacing with the operating system, file system, networking, etc.
119−\Idris{} provides a lightweight foreign function interface for achieving this,
120−as part of the prelude. For this, we assume a certain amount of knowledge of
121−C and the \texttt{gcc} compiler. First, we define a datatype which describes the external
122−types we can handle:
123−
124−\begin{code}
125−data FTy = FInt | FFloat | FChar | FString | FPtr | FUnit
126−\end{code}
127−
128−\noindent
129−Each of these corresponds directly to a C type. Respectively: \texttt{int},
130−\texttt{double}, \texttt{char}, \texttt{char*}, \texttt{void*} and \texttt{void}.
131−There is also a translation to a concrete \Idris{} type, described by the
132−following function:
133−
134−\begin{code}
135−interpFTy : FTy -> Type
136−interpFTy FInt = Int
137−interpFTy FFloat = Float
138−interpFTy FChar = Char
139−interpFTy FString = String
140−interpFTy FPtr = Ptr
141−interpFTy FUnit = ()
142−\end{code}
143−
144−\noindent
145−A foreign function is described by a list of input types and a return type, which
146−can then be converted to an \Idris{} type:
147−
148−\begin{code}
149−ForeignTy : (xs:List FTy) -> (t:FTy) -> Type
150−\end{code}
151−
152−\noindent
153−A foreign function is assumed to be impure, so \texttt{ForeignTy} builds an
154−\texttt{IO} type, for example:
155−
156−\begin{lstlisting}
157−Idris> ForeignTy [FInt, FString] FString
158−Int -> String -> IO String : Type
159−
160−Idris> ForeignTy [FInt, FString] FUnit
161−Int -> String -> IO () : Type
162−\end{lstlisting}
163−
164−\noindent
165−We build a call to a foreign function by giving the name of the function, a list of
166−argument types and the return type. The built in function \texttt{mkForeign}
167−converts this description to a function callable by \Idris{}
168−
169−\begin{code}
170−data Foreign : Type -> Type where
171− FFun : String -> (xs:List FTy) -> (t:FTy) ->
172− Foreign (ForeignTy xs t)
173−
174−mkForeign : Foreign x -> x
175−\end{code}
176−
177−\noindent
178−For example, the \texttt{putStr} function is implemented as follows, as a call to
179−an external function \texttt{putStr} defined in the run-time system:
180−
181−\begin{code}
182−putStr : String -> IO ()
183−putStr x = mkForeign (FFun "putStr" [FString] FUnit) x
184−\end{code}
185−
186−\subsubsection*{Include and linker directives}
187−
188−Foreign function calls are translated directly to calls to C functions, with appropriate
189−conversion between the \Idris{} representation of a value and the C representation.
190−Often this will require extra libraries to be linked in, or extra header and object files.
191−This is made possible through the following directives:
192−
193−\begin{itemize}
194−\item \texttt{\%lib \emph{target} "x"} --- include the \texttt{libx} library. If the target is \texttt{C} this is equivalent to passing the
195−\texttt{-lx} option to \texttt{gcc}. If the target is Java the library will be interpreted as a
196−"groupId:artifactId:packaging:version" dependency coordinate for maven.
197−\item \texttt{\%include \emph{target} "x"} --- use the header file or import \texttt{x} for the given back end target.
198−\item \texttt{\%link \emph{target} "x.o"} --- link with the object file \texttt{x.o} when using the given back end target.
199−\item \texttt{\%dynamic "x.so"} --- dynamically link the interpreter with the shared object \texttt{x.so}.
200−\end{itemize}
201−
202−\subsubsection*{Testing foreign function calls}
203−Normally, the Idris interpreter (used for typechecking and at the REPL) will
204−not perform IO actions. Additionally, as it neither generates C code nor
205−compiles to machine code, the \texttt{\%lib}, \texttt{\%include} and
206−\texttt{\%link} directives have no effect. IO actions and FFI calls can be
207−tested using the special REPL command \texttt{:x EXPR}, and C libraries can be
208−dynamically loaded in the interpreter by using the \texttt{:dynamic} command
209−or the \texttt{\%dynamic} directive. For example:
210−
211−\begin{lstlisting}
212−Idris> :dynamic libm.so
213−Idris> :x unsafePerformIO ((mkForeign (FFun "sin" [FFloat] FFloat)) 1.6)
214−0.9995736030415051 : Float
215−\end{lstlisting}
216−
217−\subsection{Type Providers}
218−Idris type providers, inspired by F\#'s type providers, are a means of making
219−our types be ``about'' something in the world outside of Idris. For example,
220−given a type that represents a database schema and a query that is checked
221−against it, a type provider could read the schema of a real database during
222−type checking.
223−
224−Idris type providers use the ordinary execution semantics of Idris to run an
225−IO action and extract the result. This result is then saved as a constant in
226−the compiled code. It can be a type, in which case it is used like any other
227−type, or it can be a value, in which case it can be used as any other value,
228−including as an index in types.
229−
230−Type providers are still an experimental extension. To enable the extension,
231−use the \texttt{\%language} directive:
232−
233−\begin{code}
234−%language TypeProviders
235−\end{code}
236−
237−A provider \texttt{p} for some type \texttt{t} is simply an expression of type
238−\texttt{IO (Provider t)}. The \texttt{\%provide} directive causes the type
239−checker to execute the action and bind the result to a name. This is perhaps
240−best illustrated with a simple example. The type provider \texttt{fromFile}
241−reads a text file. If the file consists of the string \texttt{"Int"}, then the
242−type \texttt{Int} will be provided. Otherwise, it will provide the type
243−\texttt{Nat}.
244−
245−\begin{code}
246−strToType : String -> Type
247−strToType "Int" = Int
248−strToType _ = Nat
249−
250−fromFile : String -> IO (Provider Type)
251−fromFile fname = do str <- readFile fname
252− return (Provide (strToType (trim str)))
253−\end{code}
254−
255−We then use the \texttt{\%provide} directive:
256−
257−\begin{code}
258−%provide (T1 : Type) with fromFile "theType"
259−
260−foo : T1
261−foo = 2
262−\end{code}
263−
264−\noindent
265−If the file named \texttt{theType} consists of the word \texttt{Int}, then
266−\texttt{foo} will be an \texttt{Int}. Otherwise, it will be a \texttt{Nat}.
267−When Idris encounters the directive, it first checks that the provider
268−expression \texttt{fromFile "theType"} has type \texttt{IO (Provider
269− Type)}. Next, it executes the provider. If the result is \texttt{Provide t},
270−then \texttt{T1} is defined as \texttt{t}. Otherwise, the result is an error.
271−
272−Our datatype \texttt{Provider t} has the following definition:
273−
274−\begin{code}
275−data Provider a = Error String
276− | Provide a
277−\end{code}
278−
279−\noindent
280−We have already seen the \texttt{Provide} constructor. The \texttt{Error}
281−constructor allows type providers to return useful error messages. The
282−example in this section was purposefully simple. More complex type provider
283−implementations, including a statically-checked SQLite binding, are available
284−in an external collection.\footnote{\url{https://github.com/david-christiansen/idris-type-providers}}
285−
286−\subsection{JavaScript Target}
287−
288−\Idris{} is capable of producing \emph{JavaScript} code that can be run in a browser
289−as well as in the \emph{NodeJS} environment or alike. One can use the FFI to
290−communicate with the \emph{JavaScript} ecosystem.
291−
292−\subsubsection*{Code Generation}
293−
294−\noindent
295−Code generation is split into two separate targets. To generate code that is
296−tailored for running in the browser issue the following command:
297−
298−\begin{lstlisting}[language=bash]
299−$ idris --codegen javascript hello.idr -o hello.js
300−\end{lstlisting}
301−
302−\noindent
303−The resulting file can be embedded into your HTML just like any other
304−\emph{JavaScript} code.
305−
306−\noindent
307−Generating code for \emph{NodeJS} is slightly different. \Idris{} outputs
308−a \emph{JavaScript} file that can be directly executed via \texttt{node}.
309−
310−\begin{lstlisting}[language=bash]
311−$ idris --codegen node hello.idr -o hello
312−$ ./hello
313−Hello world
314−\end{lstlisting}
315−
316−\noindent
317−Take into consideration that the \emph{JavaScript} code generator is using
318−\texttt{console.log} to write text to \texttt{stdout}, this means that it will
319−automatically add a newline to the end of each string. This behavior
320−does not show up in the \emph{NodeJS} code generator.
321−
322−\subsubsection*{Using the FFI}
323−
324−\noindent
325−To write a useful application we need to communicate with the outside
326−world. Maybe we want to manipulate the DOM or send an Ajax request. For this
327−task we can use the FFI. Since most \emph{JavaScript} APIs demand callbacks
328−we need to extend the FFI so we can pass functions as arguments.
329−
330−\noindent
331−The \emph{JavaScript} FFI works a little bit differently than the regular FFI.
332−It uses positional arguments to directly insert our arguments into a piece
333−of \emph{JavaScript} code.
334−
335−\noindent
336−One could use the primitive addition of \emph{JavaScript} like so:
337−
338−\begin{code}
339−module Main
340−
341−primPlus : Int -> Int -> IO Int
342−primPlus a b = mkForeign (FFun "%0 + %1" [FInt, FInt] FInt) a b
343−
344−main : IO ()
345−main = do
346− a <- primPlus 1 1
347− b <- primPlus 1 2
348− print (a, b)
349−\end{code}
350−
351−\noindent
352−Notice that the \texttt{\%n} notation qualifies the position of the
353−\texttt{n}-th argument given to our foreign function starting from 0. When
354−you need a percent sign rather than a position simply use \texttt{\%\%}
355−instead.
356−
357−\noindent
358−Passing functions to a foreign function is very similar. Let's assume that
359−we want to call the following function from the \emph{JavaScript} world:
360−
361−\begin{code}[language=c]
362−function twice(f, x) {
363− return f(f(x));
364−}
365−\end{code}
366−
367−\noindent
368−We obviously need to pass a function \texttt{f} here (we can infer it from
369−the way we use \texttt{f} in \texttt{twice}, it would be more obvious if
370−\emph{JavaScript} had types).
371−
372−\noindent
373−The \emph{JavaScript} FFI is able to understand functions as arguments when
374−you give it something of type \texttt{FFunction}. The following example code
375−calls \texttt{twice} in \emph{JavaScript} and returns the result to our
376−\Idris{} program:
377−
378−\begin{code}
379−module Main
380−
381−twice : (Int -> Int) -> Int -> IO Int
382−twice f x = mkForeign (
383− FFun "twice(%0,%1)" [FFunction FInt FInt, FInt] FInt
384−) f x
385−
386−main : IO ()
387−main = do
388− a <- twice (+1) 1
389− print a
390−\end{code}
391−
392−\noindent
393−The program outputs \texttt{3}, just like we expected.
394−
395−\subsubsection*{Shrinking down generated \emph{JavaScript}}
396−
397−\Idris{} can produce very big chunks of \emph{JavaScript} code. However, the
398−generated code can be minified using the \texttt{closure-compiler} from
399−Google. Any other minifier is also suitable but \texttt{closure-compiler}
400−offers advanced compilation that does some aggressive inlining and code
401−elimination. \Idris{} can take full advantage of this compilation mode and
402−it's highly recommended to use it when shipping a \emph{JavaScript}
403−application written in \Idris{}.
404−
405−\subsection{Cumulativity}
406−
407−Since values can appear in types and \emph{vice versa}, it is natural that types themselves
408−have types. For example:
409−
410−\begin{lstlisting}
411−*universe> :t Nat
412−Nat : Type
413−*universe> :t Vect
414−Vect : Nat -> Type -> Type
415−\end{lstlisting}
416−
417−\noindent
418−But what about the type of \texttt{Type}? If we ask \Idris{} it reports
419−
420−\begin{lstlisting}
421−*universe> :t Type
422−Type : Type 1
423−\end{lstlisting}
424−
425−\noindent
426−If \texttt{Type} were its own type, it would lead to an inconsitency
427−due to Girard's paradox~\cite{girard-thesis}, so internally there is a \emph{hierarchy}
428−of types (or \emph{universes}):
429−
430−\begin{code}
431−Type : Type 1 : Type 2 : Type 3 : ...
432−\end{code}
433−
434−\noindent
435−Universes are \emph{cumulative}, that is, if \texttt{x : Type n} we can also have that
436−\texttt{x : Type m}, as long as \texttt{n < m}.
437−The typechecker generates such universe
438−constraints and reports an error if any inconsistencies are found. Ordinarily, a
439−programmer does not need to worry about this, but it does prevent (contrived)
440−programs such as the following:
441−
442−\begin{code}
443−myid : (a : Type) -> a -> a
444−myid _ x = x
445−
446−idid : (a : Type) -> a -> a
447−idid = myid _ myid
448−\end{code}
449−
450−\noindent
451−The application of \texttt{myid} to itself leads to a cycle in the universe hierarchy
452−--- \texttt{myid}'s first argument is a \texttt{Type}, which cannot be at a lower level
453−than required if it is applied to itself.
454−
455−%\subsection{Comparison}
456−
457−%How does \Idris{} compare with other dependently typed languages and proof
458−%assistants, such as Coq, Agda and Epigram?
tutorial/content/modules.texdeleted−201
@@ -1,201 +0,0 @@
1−\section{Modules and Namespaces}
2−\label{sect:namespaces}
3−
4−An \Idris{} program consists of a collection of modules. Each module includes
5−an optional \texttt{module} declaration giving the name of the module, a
6−list of \texttt{import} statements giving the other modules which are to be imported,
7−and a collection of declarations and definitions of types, classes and functions.
8−For example, Figure \ref{bstmod} gives a module which defines a binary
9−tree type \texttt{BTree} (in a file \texttt{btree.idr}) and Figure
10−\ref{bstmain} gives a main program (in a file \texttt{bmain.idr} which uses the
11−\texttt{bst} module to sort a list.
12−
13−\begin{code}[caption={Binary Tree module}, label=bstmod]
14−module btree
15−
16−data BTree a = Leaf
17− | Node (BTree a) a (BTree a)
18−
19−insert : Ord a => a -> BTree a -> BTree a
20−insert x Leaf = Node Leaf x Leaf
21−insert x (Node l v r) = if (x < v) then (Node (insert x l) v r)
22− else (Node l v (insert x r))
23−
24−toList : BTree a -> List a
25−toList Leaf = []
26−toList (Node l v r) = toList l ++ (v :: toList r)
27−
28−toTree : Ord a => List a -> BTree a
29−toTree [] = Leaf
30−toTree (x :: xs) = insert x (toTree xs)
31−\end{code}
32−
33−\begin{code}[caption={Binary Tree main program},label=bstmain]
34−module Main
35−
36−import btree
37−
38−main : IO ()
39−main = do let t = toTree [1,8,2,7,9,3]
40− print (toList t)
41−\end{code}
42−
43−\noindent
44−The same names can be defined in multiple modules. This is possible because in practice names
45−are \emph{qualified} with the name of the module.
46−The names defined in the \texttt{btree} module are, in full:
47−
48−\begin{itemize}
49−\item \texttt{btree.BTree}, \texttt{btree.Leaf}, \texttt{btree.Node}, \texttt{btree.insert},
50−\texttt{btree.toList} and \texttt{btree.toTree}.
51−\end{itemize}
52−
53−\noindent
54−If names are otherwise unambiguous, there is no need to give the fully qualified name.
55−Names can be disambiguated either by giving an explicit qualification, or according to
56−their type.
57−
58−There is no formal link between the module name and its filename, although it
59−is generally advisable to use the same name for each. An \texttt{import}
60−statement refers to a filename, using dots to separate directories. For
61−example, \texttt{import foo.bar} would import the file \texttt{foo/bar.idr},
62−which would conventionally have the module declaration \texttt{module foo.bar}.
63−The only requirement for module names is that the main module, with the
64−\texttt{main} function, must be called \texttt{Main} (though its filename need
65−not be \texttt{Main.idr}).
66−
67−\subsection{Export Modifiers}
68−
69−By default, all names defined in a module are exported for use by other modules.
70−However, it is good practice only to export a minimal interface and keep internal
71−details abstract. \Idris{} allows functions, types and classes to be marked
72−as \texttt{public}, \texttt{abstract} or \texttt{private}:
73−
74−\begin{itemize}
75−\item \texttt{public} means that both the name and definition are exported.
76−For functions, this means that the implementation is exported (which means, for example,
77−it can be used in a dependent type). For data types, this means that the type name and
78−the constructors are exported. For classes, this means that the class name and
79−method names are exported.
80−\item \texttt{abstract} means that only the name is exported. For functions, this means
81−that the implementation is not exported. For data types, this means that the type name
82−is exported but not the constructors. For classes, this means that the class name is exported
83−but not the method names.
84−\item \texttt{private} means that neither the name nor the definition is exported.
85−\end{itemize}
86−
87−\noindent
88−If any definition is given an export modifier, then all names with no modifier are assumed
89−to be \texttt{private}. For our \texttt{btree} module, it makes sense for the
90−tree data type and the functions to be exported as \texttt{abstract}, as we see in
91−Figure \ref{bstmodp}.
92−
93−\begin{code}[caption={Binary Tree module, with export modifiers}, label=bstmodp]
94−module btree
95−
96−abstract data BTree a = Leaf
97− | Node (BTree a) a (BTree a)
98−
99−abstract
100−insert : Ord a => a -> BTree a -> BTree a
101−insert x Leaf = Node Leaf x Leaf
102−insert x (Node l v r) = if (x < v) then (Node (insert x l) v r)
103− else (Node l v (insert x r))
104−
105−abstract
106−toList : BTree a -> List a
107−toList Leaf = []
108−toList (Node l v r) = app (toList l) (v :: toList r)
109−
110−abstract
111−toTree : Ord a => List a -> BTree a
112−toTree [] = Leaf
113−toTree (x :: xs) = insert x (toTree xs)
114−\end{code}
115−
116−\noindent
117−Finally, the default export mode can be changed with the \texttt{\%access} directive,
118−for example:
119−
120−\begin{code}
121−%access abstract
122−\end{code}
123−
124−\noindent
125−In this case, any function with no access modifier will be exported as \texttt{abstract},
126−rather than left \texttt{private}.
127−
128−\subsection{Explicit Namespaces}
129−
130−Defining a module also defines a namespace implicitly. However, namespaces can also
131−be given \emph{explicitly}. This is most useful if you wish to overload names within
132−the same module:
133−
134−\begin{code}
135−module foo
136−
137−namespace x
138− test : Int -> Int
139− test x = x * 2
140−
141−namespace y
142− test : String -> String
143− test x = x ++ x
144−\end{code}
145−
146−\noindent
147−This (admittedly contrived) module defines two functions with fully qualified names
148−\texttt{foo.x.test} and \texttt{foo.y.test}, which can be disambiguated by their
149−types:
150−
151−\begin{lstlisting}
152−*foo> test 3
153−6 : Int
154−*foo> test "foo"
155−"foofoo" : String
156−\end{lstlisting}
157−
158−\subsection{Parameterised blocks}
159−
160−Groups of functions can be parameterised over a number of arguments using a
161−\texttt{parameters} declaration, for example:
162−
163−\begin{code}
164−parameters (x : Nat, y : Nat)
165− addAll : Nat -> Nat
166− addAll z = x + y + z
167−\end{code}
168−
169−\noindent
170−The effect of a \texttt{parameters} block is to add the declared parameters to every
171−function, type and data constructor within the block. Outside the block, the parameters
172−must be given explicitly:
173−
174−\begin{lstlisting}
175−*params> :t addAll
176−addAll : Nat -> Nat -> Nat -> Nat
177−\end{lstlisting}
178−
179−\noindent
180−Parameters blocks can be nested, and can also include data declarations, in
181−which case the parameters are added explicitly to all type and data
182−constructors. They may also be dependent types with implicit arguments:
183−
184−\begin{code}
185−parameters (xs : Vect x a, y : Nat)
186− data Vects : Type -> Type where
187− MkVects : Vect a y -> Vects a
188−
189− append : Vects a -> Vect (x + y) a
190− append (MkVects ys) = xs ++ ys
191−\end{code}
192−
193−\noindent
194−To use \texttt{Vects} or \texttt{append} outside the block, we must also
195−give the \texttt{xs} and \texttt{y} arguments. Here, we can use placeholders for
196−the values which can be inferred by the type checker:
197−
198−\begin{lstlisting}
199−*params> show (append _ _ (MkVects [1,2,3] _ [4,5,6]))
200−"[1, 2, 3, 4, 5, 6]" : String
201−\end{lstlisting}
tutorial/content/provisional.texdeleted−284
@@ -1,284 +0,0 @@
1−\section{Provisional Definitions}
2−
3−\label{sect:provisional}
4−
5−Sometimes when programming with dependent types, the type required by the type
6−checker and the type of the program we have written will be different (in that
7−they do not have the same normal form), but nevertheless provably equal. For
8−example, recall the \texttt{parity} function:
9−
10−\begin{code}
11−data Parity : Nat -> Type where
12− even : Parity (n + n)
13− odd : Parity (S (n + n))
14−
15−parity : (n:Nat) -> Parity n
16−\end{code}
17−
18−\noindent
19−We'd like to implement this as follows:
20−
21−\begin{code}
22−parity : (n:Nat) -> Parity n
23−parity Z = even {n=Z}
24−parity (S Z) = odd {n=Z}
25−parity (S (S k)) with (parity k)
26− parity (S (S (j + j))) | even = even {n=S j}
27− parity (S (S (S (j + j)))) | odd = odd {n=S j}
28−\end{code}
29−
30−\noindent
31−This simply states that zero is even, one is odd, and recursively, the parity
32−of \texttt{k+2} is the same as the parity of \texttt{k}.
33−Explicitly marking the value of \texttt{n} in
34−even and odd is necessary to help type inference. Unfortunately, the type
35−checker rejects this:
36−
37−\begin{code}
38−views.idr:12:Can't unify Parity (plus (S j) (S j)) with
39−Parity (S (S (plus j j)))
40−\end{code}
41−
42−\noindent
43−The type checker
44−is telling us that \texttt{(j+1)+(j+1)} and \texttt{2+j+j}
45−do not normalise to the same value.
46−This is because \texttt{plus} is defined by recursion on its first argument, and in the
47−second value, there is a successor symbol on the second argument, so this will
48−not help with reduction. These values are obviously equal --- how can we rewrite the program to fix this problem?
49−
50−\subsection{Provisional definitions}
51−
52−\emph{Provisional definitions} help with this problem by allowing us to defer the
53−proof details until a later point. There are two main reasons why they are
54−useful.
55−
56−\begin{itemize}
57−\item When \emph{prototyping}, it is useful to be able to test programs before
58−finishing all the details of proofs.
59−\item When \emph{reading} a program, it is often much clearer to defer the proof
60−details so that they do not distract the reader from the underlying algorithm.
61−\end{itemize}
62−
63−\noindent
64−Provisional definitions are written in the same way as ordinary definitions,
65−except that they introduce the right hand side with a \texttt{?=} rathar than
66−\texttt{=}. We define
67−\texttt{parity} as follows:
68−
69−\begin{code}
70−parity : (n:Nat) -> Parity n
71−parity Z = even {n=Z}
72−parity (S Z) = odd {n=Z}
73−parity (S (S k)) with (parity k)
74− parity (S (S (j + j))) | even ?= even {n=S j}
75− parity (S (S (S (j + j)))) | odd ?= odd {n=S j}
76−\end{code}
77−
78−\noindent
79−When written in this form, instead of reporting a type error, \Idris{} will insert
80−a metavariable standing for a theorem which will correct the type error. \Idris{}
81−tells us we have two proof obligations, with names generated from the module and
82−function names:
83−
84−\begin{lstlisting}
85−*views> :m
86−Global metavariables:
87− [views.parity_lemma_2,views.parity_lemma_1]
88−\end{lstlisting}
89−
90−\noindent
91−The first of these has the following type:
92−
93−\begin{lstlisting}
94−*views> :p views.parity_lemma_1
95−
96−---------------------------------- (views.parity_lemma_1) --------
97−{hole0} : (j : Nat) -> (Parity (plus (S j) (S j))) -> Parity (S (S (j + j)))
98−
99−-views.parity_lemma_1>
100−\end{lstlisting}
101−
102−\noindent
103−The two arguments are \texttt{j}, the variable in scope from the pattern match,
104−and \texttt{value}, which is the value we gave in the right hand side of the
105−provisional definition. Our goal is to rewrite the type so that we can use
106−this value.
107−We can achieve this using the following theorem from
108−the prelude:
109−
110−\begin{code}
111−plusSuccRightSucc : (left : Nat) -> (right : Nat) ->
112− S (left + right) = left + (S right)
113−\end{code}
114−
115−\noindent
116−After applying \texttt{intro} twice, we have:
117−
118−\begin{lstlisting}
119−-views.parity_lemma_1> intro
120−
121− j : Nat
122− value : Parity (S (plus j (S j)))
123−---------------------------------- (views.parity_lemma_1) --------
124−{hole2} : Parity (S (S (j + j)))
125−\end{lstlisting}
126−
127−\noindent
128−We need to use \texttt{compute} again to unfold the definition of \texttt{(+)}.
129−
130−\begin{lstlisting}
131−-views.parity_lemma_1> intro
132−
133− j : Nat
134− value : Parity (S (plus j (S j)))
135−---------------------------------- (views.parity_lemma_1) --------
136−{hole2} : Parity (S (S (plus j j)))
137−\end{lstlisting}
138−
139−\noindent
140−Then we apply the \texttt{plusSuccRightSucc} rewrite rule, symmetrically,
141−to \texttt{j} and \texttt{j}, giving:
142−
143−\begin{lstlisting}
144−-views.parity_lemma_1> rewrite sym (plusSuccRightSucc j j)
145−
146− j : Nat
147− value : Parity (S (plus j (S j)))
148−---------------------------------- (views.parity_lemma_1) --------
149−{hole3} : Parity (S (plus j (S j)))
150−\end{lstlisting}
151−
152−\noindent
153−\texttt{sym} is a function, defined in the library, which reverses the order of the rewrite:
154−
155−\begin{lstlisting}
156−sym : l = r -> r = l
157−sym refl = refl
158−\end{lstlisting}
159−
160−\noindent
161−We can complete this proof using the \texttt{trivial} tactic, which finds
162−\texttt{value} in the premisses. The proof of the second lemma proceeds in
163−exactly the same way.
164−
165−We can now test the \texttt{natToBin} function from Section
166−\ref{sect:nattobin} at the prompt. 42 is 101010 in
167−binary. The binary digits are reversed:
168−
169−\begin{lstlisting}
170−*views> show (natToBin 42)
171−"[False, True, False, True, False, True]" : String
172−\end{lstlisting}
173−
174−
175−\subsection{Suspension of Disbelief}
176−
177−\Idris{} requires that proofs be complete before compiling programs (although
178−evaluation at the prompt is possible without proof details). Sometimes,
179−especially when prototyping, it is easier not to have to do this. It might even
180−be beneficial to test programs before attempting to prove things about them ---
181−if testing finds an error, you know you had better not waste your time proving
182−something!
183−
184−Therefore, \Idris{} provides a built-in coercion function, which allows you to use
185−a value of the incorrect types:
186−
187−\begin{code}
188−believe_me : a -> b
189−\end{code}
190−
191−\noindent
192−Obviously, this should be used with extreme caution. It is useful when prototyping, and
193−can also be appropriate when asserting properties of external code (perhaps in an
194−external C library). The ``proof'' of \texttt{views.parity\_lemma\_1} using this is:
195−
196−\begin{lstlisting}
197−views.parity_lemma_2 = proof {
198− intro;
199− intro;
200− exact believe_me value;
201−}
202−\end{lstlisting}
203−
204−\noindent
205−The \texttt{exact} tactic allows us to provide an exact value for the proof. In this case,
206−we assert that the value we gave was correct.
207−
208−\subsection{Example: Binary numbers}
209−
210−Previously, we implemented conversion to binary numbers using the \texttt{Parity} view.
211−Here, we show how to use the same view to implement a verified conversion to
212−binary.
213−We begin by indexing binary numbers over their \texttt{Nat} equivalent. This is a common
214−pattern, linking a representation (in this case \texttt{Binary}) with a meaning (in this
215−case \texttt{Nat}):
216−
217−\begin{code}
218−data Binary : Nat -> Type where
219− bEnd : Binary Z
220− bO : Binary n -> Binary (n + n)
221− bI : Binary n -> Binary (S (n + n))
222−\end{code}
223−
224−\noindent
225−\texttt{bO} and \texttt{bI} take a binary number as an argument and effectively shift it one bit
226−left, adding either a zero or one as the new least significant bit. The index,
227−\texttt{n + n} or \texttt{S (n + n)} states the result that this left shift then add will
228−have to the meaning of the number. This will result in a representation with
229−the least significant bit at the front.
230−
231−Now a function which converts a Nat to binary will state, in the type, that the
232−resulting binary number is a faithful representation of the original Nat:
233−
234−\begin{code}
235−natToBin : (n:Nat) -> Binary n
236−\end{code}
237−
238−\noindent
239−The \texttt{Parity} view makes the definition fairly simple --- halving the
240−number is effectively a right shift after all --- although we need to use a
241−provisional definition in the odd case:
242−
243−\begin{code}
244−natToBin : (n:Nat) -> Binary n
245−natToBin Z = bEnd
246−natToBin (S k) with (parity k)
247− natToBin (S (j + j)) | even = bI (natToBin j)
248− natToBin (S (S (j + j))) | odd ?= bO (natToBin (S j))
249−\end{code}
250−
251−\noindent
252−The problem with the odd case is the same as in the definition of \texttt{parity}, and
253−the proof proceeds in the same way:
254−
255−\begin{code}
256−natToBin_lemma_1 = proof {
257− intro;
258− intro;
259− rewrite sym (plusSuccRightSucc j j);
260− trivial;
261−}
262−\end{code}
263−
264−\noindent
265−To finish, we'll implement a main program which reads an integer from the user and
266−outputs it in binary.
267−
268−\begin{code}
269−main : IO ()
270−main = do putStr "Enter a number: "
271− x <- getLine
272− print (natToBin (fromInteger (cast x)))
273−\end{code}
274−
275−\noindent
276−For this to work, of course, we need a \texttt{Show} instance for \texttt{Binary n}:
277−
278−\begin{code}
279−instance Show (Binary n) where
280− show (bO x) = show x ++ "0"
281− show (bI x) = show x ++ "1"
282− show bEnd = ""
283−\end{code}
284−
tutorial/content/starting.texdeleted−145
@@ -1,145 +0,0 @@
1−\section{Getting Started}
2−
3−\subsection{Prerequisites}
4−
5−Before installing \Idris{}, you will need to make sure you have all of the necessary
6−libraries and tools. You will need:
7−
8−\begin{itemize}
9−\item A fairly recent Haskell platform. Version 2010.1.0.0.1 is currently
10−sufficiently recent.
11−\item The GNU multiprecision arithmetic library, GMP, available from MacPorts and
12−all major Linux distributions.
13−\end{itemize}
14−
15−\subsection{Downloading and Installing}
16−
17−The easiest way to install \Idris{}, if you have all of the prerequisites, is to type:
18−
19−\begin{lstlisting}[language=bash]
20−cabal update; cabal install idris
21−\end{lstlisting}
22−
23−\noindent
24−This will install the latest version released on Hackage, along with any dependencies.
25−If, however, you would like the most up
26−to date development version, you can find it on GitHub at
27−\url{https://github.com/edwinb/Idris-dev}.
28−
29−To check that installation has succeeded, and to write your first \Idris{}
30−program, create a file called ``\texttt{hello.idr}'' containing the following
31−text:
32−
33−\begin{code}
34−module Main
35−
36−main : IO ()
37−main = putStrLn "Hello world"
38−\end{code}
39−
40−\noindent
41−If you are familiar with Haskell, it should be fairly clear what the program is doing
42−and how it works, but if not, we will explain the details later.
43−You can compile the program to an executable by entering \texttt{idris hello.idr -o hello}
44−at the shell prompt. This will create an executable called \texttt{hello}, which you can run:
45−
46−\begin{lstlisting}[language=bash]
47−$ idris hello.idr -o hello
48−$ ./hello
49−Hello world
50−\end{lstlisting}
51−
52−\noindent
53−Note that the \texttt{\$} indicates the shell prompt! Some useful options to the
54−\texttt{idris} command are:
55−
56−\begin{itemize}
57−\item \texttt{-o prog} to compile to an executable called \texttt{prog}.
58−\item \texttt{--check} type check the file and its dependencies without starting the
59−interactive environment.
60−\item \texttt{--help} display usage summary and command line options
61−\end{itemize}
62−
63−\subsection{The interactive environment}
64−
65−Entering \texttt{idris} at the shell prompt starts up the interactive
66−environment. You should see something like the following:
67−
68−\begin{lstlisting}[escapechar=^]
69−$ idris
70− ____ __ _
71− / _/___/ /____(_)____
72− / // __ / ___/ / ___/ Version ^\version{}^
73− _/ // /_/ / / / (__ ) http://www.idris-lang.org/
74− /___/\__,_/_/ /_/____/ Type :? for help
75−
76−Idris>
77−\end{lstlisting}
78−
79−\noindent
80−This gives a \texttt{ghci}-style interface which allows evaluation of expressions,
81−as well as type checking expressions, theorem proving, compilation, editing
82−and various other operations. \texttt{:?} gives a list of supported commands,
83−as shown in Figure \ref{cmds}. Figure \ref{run1} shows an example run in which
84−\texttt{hello.idr} is loaded, the type of \texttt{main} is checked and then
85−the program is compiled to the executable \texttt{hello}.
86−
87−\begin{lstlisting}[caption={Interactive environment commands}, label=cmds, escapechar=^]
88−Idris version ^\version{}^
89−--------------------
90−
91− Command Arguments Purpose
92−
93− <expr> Evaluate an expression
94− :t <expr> Check the type of an expression
95− :miss :missing <name> Show missing clauses
96− :i :info <name> Display information about a type class
97− :total <name> Check the totality of a name
98− :r :reload Reload current file
99− :l :load <filename> Load a new file
100− :cd <filename> Change working directory
101− :m :module <module> Import an extra module
102− :e :edit Edit current file using $EDITOR or $VISUAL
103− :m :metavars <metavar> Show remaining proof obligations (metavariables)
104− :p :prove <metavar> Prove a metavariable
105− :a :addproof <name> Add proof to source file
106− :rmproof <name> Remove proof from proof stack
107− :showproof <name> Show proof
108− :proofs Show available proofs
109− :x <expr> Execute IO actions resulting from an expression
110− using the interpreter
111− :c :compile <filename> Compile to an executable <filename>
112− :js :javascript <filename> Compile to JavaScript <filename>
113− :exec :execute Compile to an executable and run
114− :dynamic <filename> Dynamically load a C library (similar to %dynamic)
115− :dynamic List dynamically loaded C libraries
116− :? :h :help Display this help text
117− :set <option> Set an option (errorcontext, showimplicits)
118− :unset <option> Unset an option
119− :colour :color <option> Turn REPL colours on or off; set a specific colour
120− :q :quit Exit the Idris system
121−\end{lstlisting}
122−
123−\begin{lstlisting}[caption={Sample Interactive Run}, label=run1, escapechar=^]
124−$ idris hello.idr
125− ____ __ _
126− / _/___/ /____(_)____
127− / // __ / ___/ / ___/ Version ^\version{}^
128− _/ // /_/ / / / (__ ) http://www.idris-lang.org/
129− /___/\__,_/_/ /_/____/ Type :? for help
130−
131−Type checking ./hello.idr
132−*hello> :t main
133−main : IO ()
134−*hello> :c hello
135−*hello> :q
136−Bye bye
137−$ ./hello
138−Hello world
139−\end{lstlisting}
140−
141−\noindent
142−Type checking a file, if successful, creates a bytecode version of the file (in
143−this case \texttt{hello.ibc}) to speed up loading in future. The bytecode is
144−regenerated if the source file changes.
145−
tutorial/content/syntax.texdeleted−104
@@ -1,104 +0,0 @@
1−\section{Syntax Extensions}
2−
3−\Idris{} supports the implementation of Embedded Domain Specific Languages (EDSLs) in
4−several ways~\cite{res-dsl-padl12}. One way, as we have already seen, is through
5−extending \texttt{do} notation. Another important way is to allow extension of the core
6−syntax. In this section we describe two ways of extending the syntax: \texttt{syntax}
7−rules and \texttt{dsl} notation.
8−
9−\subsection{\texttt{syntax} rules}
10−
11−We have seen \texttt{if...then...else} expressions, but these
12−are not built in --- instead, we define a function in the prelude\ldots
13−
14−\begin{code}
15−boolElim : (x:Bool) -> |(t : a) -> |(f : a) -> a;
16−boolElim True t e = t;
17−boolElim False t e = e;
18−\end{code}
19−
20−\noindent
21−\ldots and extend the core syntax with a \texttt{syntax} declaration:
22−
23−\begin{code}
24−syntax if [test] then [t] else [e] = boolElim test t e;
25−\end{code}
26−
27−\noindent
28−The left hand side of a \texttt{syntax} declaration describes the syntax rule, and the right
29−hand side describes its expansion. The syntax rule itself consists of:
30−
31−\begin{itemize}
32−\item \textbf{Keywords} --- here, \texttt{if}, \texttt{then} and \texttt{else}, which must
33−be valid identifiers
34−\item \textbf{Non-terminals} --- included in square brackets, \texttt{[test]}, \texttt{[t]}
35−and \texttt{[e]} here, which stand for arbitrary expressions. To avoid parsing ambiguities,
36−these expressions cannot use syntax extensions at the top level (though they can be used
37−in parentheses).
38−\item \textbf{Names} --- included in braces, which stand for names which may be bound
39−on the right hand side.
40−\item \textbf{Symbols} --- included in quotations marks, e.g. \texttt{":="}. This can
41−also be used to include reserved words in syntax rules, such as \texttt{"let"} or \texttt{"in"}.
42−\end{itemize}
43−
44−\noindent
45−The limitations on the form of a syntax rule are that it must include at least
46−one symbol or keyword, and there must be no repeated variables standing for
47−non-terminals. Any expression can be used, but if there are two non-terminals
48−in a row in a rule, only simple expressions may be used (that is, variables,
49−constants, or bracketed expressions). Rules can use previously defined rules,
50−but may not be recursive. The following syntax extensions would therefore be
51−valid:
52−
53−\begin{code}
54−syntax [var] ":=" [val] = Assign var val;
55−syntax [test] "?" [t] ":" [e] = if test then t else e;
56−syntax select [x] from [t] where [w] = SelectWhere x t w;
57−syntax select [x] from [t] = Select x t;
58−\end{code}
59−
60−\noindent
61−Syntax macros can be further restricted to apply only in patterns (i.e., only on the left
62−hand side of a pattern match clause) or only in terms (i.e. everywhere but the left hand side
63−of a pattern match clause) by being marked as \texttt{pattern} or \texttt{term} syntax
64−rules. For example, we might define an interval as follows, with a static check
65−that the lower bound is below the upper bound using \texttt{so}:
66−
67−\begin{code}
68−data Interval : Type where
69− MkInterval : (lower : Float) -> (upper : Float) ->
70− so (lower < upper) -> Interval
71−\end{code}
72−
73−\noindent
74−We can define a syntax which, in patterns, always matches \texttt{oh} for the proof
75−argument, and in terms requires a proof term to be provided:
76−
77−\begin{code}
78−pattern syntax "[" [x] "..." [y] "]" = MkInterval x y oh
79−term syntax "[" [x] "..." [y] "]" = MkInterval x y ?bounds_lemma
80−\end{code}
81−
82−\noindent
83−In terms, the syntax \texttt{[x...y]} will generate a proof obligation
84−\texttt{bounds\_lemma} (possibly renamed).
85−
86−Finally, syntax rules may be used to introduce alternative binding forms. For
87−exampe, a \texttt{for} loop binds a variable on each iteration:
88−
89−\begin{code}
90−syntax for {x} "in" [xs] ":" [body] = forLoop xs (\x => body)
91−
92−main : IO ()
93−main = do for x in [1..10]:
94− putStrLn ("Number " ++ show x)
95− putStrLn "Done!"
96−\end{code}
97−
98−\noindent
99−Note that we have used the \texttt{\{x\}} form to state that \texttt{x} represents
100−a bound variable, substituted on the right hand side. We have also put \texttt{"in"} in
101−quotation marks since it is already a reserved word.
102−
103−\input{./content/dsl}
104−
tutorial/content/theorems.texdeleted−377
@@ -1,377 +0,0 @@
1−\section{Theorem Proving}
2−
3−\subsection{Equality}
4−
5−\Idris{} allows propositional equalities to be declared, allowing theorems about
6−programs to be stated and proved. Equality is built in, but conceptually has
7−the following definition:
8−
9−\begin{code}
10−data (=) : a -> b -> Type where
11− refl : x = x
12−\end{code}
13−
14−\noindent
15−Equalities can be proposed between any values of any types, but the only way to
16−construct a proof of equality is if values actually are equal. For example:
17−
18−\begin{code}
19−fiveIsFive : 5 = 5
20−fiveIsFive = refl
21−
22−twoPlusTwo : 2 + 2 = 4
23−twoPlusTwo = refl
24−\end{code}
25−
26−\subsection{The Empty Type}
27−
28−\label{sect:empty}
29−
30−There is an empty type, \texttt{\_|\_}, which has no constructors. It is
31−therefore impossible to construct an element of the empty type, at least
32−without using a partially defined or general recursive function (see Section
33−\ref{sect:totality} for more details). We can therefore use the empty type
34−to prove that something is impossible, for example zero is never equal
35−to a successor:
36−
37−\begin{code}
38−disjoint : (n : Nat) -> Z = S n -> _|_
39−disjoint n p = replace {P = disjointTy} p ()
40− where
41− disjointTy : Nat -> Type
42− disjointTy Z = ()
43− disjointTy (S k) = _|_
44−\end{code}
45−
46−\noindent
47−There is no need to worry too much about how this function works --- essentially,
48−it applies the library function \texttt{replace}, which uses an equality proof to
49−transform a predicate. Here we use it to transform a value of a type which can exist,
50−the empty tuple, to a value of a type which can't, by using a proof of something which can't exist.
51−
52−Once we have an element of the empty type, we can prove anything. \texttt{FalseElim}
53−is defined in the library, to assist with proofs by contradiction.
54−
55−\begin{code}
56−FalseElim : _|_ -> a
57−\end{code}
58−
59−\subsection{Simple Theorems}
60−
61−When type checking dependent types, the type itself gets \emph{normalised}. So imagine
62−we want to prove the following theorem about the reduction behaviour of \texttt{plus}:
63−
64−\begin{code}
65−plusReduces : (n:Nat) -> plus Z n = n
66−\end{code}
67−
68−\noindent
69−We've written down the statement of the theorem as a type, in just the same way
70−as we would write the type of a program. In fact there is no real distinction
71−between proofs and programs. A proof, as far as we are concerned here, is
72−merely a program with a precise enough type to guarantee a particular property
73−of interest.
74−
75−We won't go into details here, but the Curry-Howard
76−correspondence~\cite{howard} explains this relationship.
77−The proof itself is trivial, because \texttt{plus Z n} normalises to \texttt{n}
78−by the definition of \texttt{plus}:
79−
80−\begin{code}
81−plusReduces n = refl
82−\end{code}
83−
84−\noindent
85−It is slightly harder if we try the arguments the other way, because plus is
86−defined by recursion on its first argument. The proof also works by recursion
87−on the first argument to \texttt{plus}, namely \texttt{n}.
88−
89−\begin{code}
90−plusReducesZ : (n:Nat) -> n = plus n Z
91−plusReducesZ Z = refl
92−plusReducesZ (S k) = cong (plusReducesZ k)
93−\end{code}
94−
95−\noindent
96−\texttt{cong} is a function defined in the library which states that
97−equality respects function application:
98−
99−\begin{code}
100−cong : {f : t -> u} -> a = b -> f a = f b
101−\end{code}
102−
103−\noindent
104−We can do the same for the reduction behaviour of plus on successors:
105−
106−\begin{code}
107−plusReducesS : (n:Nat) -> (m:Nat) -> S (plus n m) = plus n (S m)
108−plusReducesS Z m = refl
109−plusReducesS (S k) m = cong (plusReducesS k m)
110−\end{code}
111−
112−\noindent
113−Even for trival theorems like these, the proofs are a little tricky to
114−construct in one go. When things get even slightly more complicated, it becomes
115−too much to think about to construct proofs in this 'batch mode'. \Idris{}
116−therefore provides an interactive proof mode.
117−
118−\subsection{Interactive theorem proving}
119−
120−Instead of writing the proof in one go, we can use \Idris{}'s interactive
121−proof mode. To do this, we write the general \emph{structure} of the proof,
122−and use the interactive mode to complete the details. We'll be constructing
123−the proof by \emph{induction}, so we write the cases for \texttt{Z} and
124−\texttt{S}, with a recursive call in the \texttt{S} case giving the inductive
125−hypothesis, and insert \emph{metavariables} for the rest of the definition:
126−
127−\begin{code}
128−plusReducesZ' : (n:Nat) -> n = plus n Z
129−plusReducesZ' Z = ?plusredZ_Z
130−plusReducesZ' (S k) = let ih = plusReducesZ' k in
131− ?plusredZ_S
132−\end{code}
133−
134−\noindent
135−On running \Idris{}, two global names are created, \texttt{plusredZ\_O} and
136−\texttt{plusredZ\_S}, with no definition. We can use the \texttt{:m} command
137−at the prompt to find out which metavariables are still to be solved (or, more
138−precisely, which functions exist but have no definitions), then the
139−\texttt{:t} command to see their types:
140−
141−\begin{lstlisting}
142−*theorems> :m
143−Global metavariables:
144− [plusredZ_S,plusredZ_Z]
145−
146−\end{lstlisting}
147−
148−\begin{lstlisting}
149−*theorems> :t plusredZ_Z
150−plusredZ_Z : Z = plus Z Z
151−
152−*theorems> :t plusredZ_S
153−plusredZ_S : (k : Nat) -> (k = plus k Z) -> S k = plus (S k) Z
154−\end{lstlisting}
155−
156−\noindent
157−The \texttt{:p} command enters interactive proof mode, which can be used to complete
158−the missing definitions.
159−
160−\begin{lstlisting}
161−*theorems> :p plusredZ_Z
162−
163−---------------------------------- (plusredZ_Z) --------
164−{hole0} : Z = plus Z Z
165−\end{lstlisting}
166−
167−\noindent
168−This gives us a list of premisses
169−(above the line; there are none here) and the current goal (below the line;
170−named \texttt{\{hole0\}} here).
171−At the prompt we can enter tactics to direct the construction of the proof. In this case,
172−we can normalise the goal with the \texttt{compute} tactic:
173−
174−\begin{lstlisting}
175−-plusredZ_Z> compute
176−
177−---------------------------------- (plusredZ_Z) --------
178−{hole0} : Z = Z
179−\end{lstlisting}
180−
181−\noindent
182−Now we have to prove that \texttt{Z} equals \texttt{Z}, which is easy to prove by
183−\texttt{refl}. To apply a function, such as \texttt{refl}, we use \texttt{refine}
184−which introduces subgoals for each of the function's explicit arguments (\texttt{refl}
185−has none):
186−
187−\begin{lstlisting}
188−-plusredZ_Z> refine refl
189−plusredZ_Z: no more goals
190−\end{lstlisting}
191−
192−\noindent
193−Here, we could also have used the \texttt{trivial} tactic, which tries to refine by
194−\texttt{refl}, and if that fails, tries to refine by each name in the local context.
195−When a proof is complete, we use the \texttt{qed} tactic to add the proof to the
196−global context, and remove the metavariable from the unsolved metavariables list.
197−This also outputs a trace of the proof:
198−
199−\begin{code}
200−-plusredZ_Z> qed
201−plusredZ_Z = proof {
202− compute;
203− refine refl;
204−}
205−\end{code}
206−
207−\begin{lstlisting}
208−*theorems> :m
209−Global metavariables:
210− [plusredZ_S]
211−\end{lstlisting}
212−
213−\noindent
214−The \texttt{:addproof} command, at the interactive prompt, will add the proof to
215−the source file (effectively in an appendix).
216−Let us now prove the other required lemma, \texttt{plusredZ\_S}:
217−
218−\begin{lstlisting}
219−*theorems> :p plusredZ_S
220−
221−---------------------------------- (plusredZ_S) --------
222−{hole0} : (k : Nat) -> (k = plus k Z) -> S k = plus (S k) Z
223−\end{lstlisting}
224−
225−\noindent
226−In this case, the goal is a function type, using \texttt{k} (the argument accessible by
227−pattern matching) and \texttt{ih} (the local variable containing the result of
228−the recursive call). We can introduce these as premisses using the \texttt{intro} tactic
229−twice (or \texttt{intros}, which introduces all arguments as premisses). This gives:
230−
231−\begin{lstlisting}
232− k : Nat
233− ih : k = plus k Z
234−---------------------------------- (plusredZ_S) --------
235−{hole2} : S k = plus (S k) Z
236−\end{lstlisting}
237−
238−\noindent
239−Since plus is defined is defined by recursion on its first argument, the term
240−\texttt{plus (S k) Z} in the goal can be simplified, so we use
241−\texttt{compute}.
242−
243−\begin{lstlisting}
244− k : Nat
245− ih : k = plus k Z
246−---------------------------------- (plusredZ_S) --------
247−{hole2} : S k = S (plus k Z)
248−\end{lstlisting}
249−
250−\noindent
251−We know, from the type of \texttt{ih}, that \texttt{k = plus k Z}, so we would like to
252−use this knowledge to replace \texttt{plus k Z} in the goal with \texttt{k}. We can
253−achieve this with the \texttt{rewrite} tactic:
254−
255−\begin{lstlisting}
256−-plusredZ_S> rewrite ih
257−
258− k : Nat
259− ih : k = plus k Z
260−---------------------------------- (plusredZ_S) --------
261−{hole3} : S k = S k
262−
263−-plusredZ_S>
264−\end{lstlisting}
265−
266−\noindent
267−The \texttt{rewrite} tactic takes an equality proof as an argument, and tries to rewrite
268−the goal using that proof. Here, it results in an equality which is trivially provable:
269−
270−\begin{lstlisting}
271−-plusredZ_S> trivial
272−plusredZ_S: no more goals
273−-plusredZ_S> qed
274−plusredZ_S = proof {
275− intros;
276− rewrite ih;
277− trivial;
278−}
279−\end{lstlisting}
280−
281−\noindent
282−Again, we can add this proof to the end of our source file using the \texttt{:addproof}
283−command at the interactive prompt.
284−
285−\subsection{Totality Checking}
286−
287−\label{sect:totality}
288−
289−If we really want to trust our proofs, it is important that they are defined by
290−\emph{total} functions --- that is, a function which is defined for all
291−possible inputs and is guaranteed to terminate. Otherwise we could construct an
292−element of the empty type, from which we could prove anything:
293−
294−\begin{code}
295−-- making use of 'hd' being partially defined
296−empty1 : _|_
297−empty1 = hd [] where
298− hd : List a -> a
299− hd (x :: xs) = x
300−
301−-- not terminating
302−empty2 : _|_
303−empty2 = empty2
304−\end{code}
305−
306−\noindent
307−Internally, \Idris{} checks every definition for totality, and we can check at
308−the prompt with the \texttt{:total} command. We see that neither of the above
309−definitions is total:
310−
311−\begin{lstlisting}
312−*theorems> :total empty1
313−possibly not total due to: empty1#hd
314− not total as there are missing cases
315−*theorems> :total empty2
316−possibly not total due to recursive path empty2
317−\end{lstlisting}
318−
319−\noindent
320−Note the use of the word ``possibly'' --- a totality check can, of course,
321−never be certain due to the undecidability of the halting problem. The check
322−is, therefore, conservative. It is also possible (and indeed advisable, in the
323−case of proofs) to mark functions as total so that it will be a compile time
324−error for the totality check to fail:
325−
326−\begin{lstlisting}
327−total empty2 : _|_
328−empty2 = empty2
329−
330−Type checking ./theorems.idr
331−theorems.idr:25:empty2 is possibly not total due to recursive path empty2
332−\end{lstlisting}
333−
334−\noindent
335−Reassuringly, our proof in Section \ref{sect:empty} that the zero and successor constructors
336−are disjoint is total:
337−
338−\begin{lstlisting}
339−*theorems> :total disjoint
340−Total
341−\end{lstlisting}
342−
343−\noindent
344−The totality check is, necessarily, conservative. To be recorded as total, a
345−function \texttt{f} must:
346−
347−\begin{itemize}
348−\item Cover all possible inputs
349−\item Be \emph{well-founded} --- i.e. by the time a sequence of
350−(possibly mutually) recursive calls reaches \texttt{f} again, it must
351−be possible to show that one of its arguments has decreased.
352−\item Not use any data types which are not \emph{strictly positive}
353−\item Not call any non-total functions
354−\end{itemize}
355−
356−\subsubsection{Directives and Compiler Flags for Totality}
357−
358−By default, \Idris{} allows all definitions, whether total or not. However,
359−it is desirable for functions to be total as far as possible, as this
360−provides a guarantee that they provide a result for all possible inputs,
361−in finite time. It is possible to make total functions a requirement,
362−either:
363−
364−\begin{itemize}
365−\item By using the \texttt{--total} compiler flag.
366−\item By adding a \texttt{\%default total} directive to a source file.
367−All definitions after this will be required to be total, unless
368−explicitly flagged as \texttt{partial}.
369−\end{itemize}
370−
371−\noindent
372−All functions \remph{after} a \texttt{\%default total} declaration are required
373−to be total. Correspondingly, after a \texttt{\%default partial} declaration,
374−the requirement is relaxed.
375−
376−Finally, the compiler flag \texttt{--warnpartial} causes \Idris{} to print
377−a warning for any undeclared partial function.
tutorial/content/typesfuns.texdeleted−1017
@@ -1,1017 +0,0 @@
1−\section{Types and Functions}
2−
3−\subsection{Primitive Types}
4−
5−\Idris{} defines several primitive types: \tTC{Int}, \tTC{Integer} and
6−\tTC{Float} for numeric operations, \tTC{Char} and \tTC{String} for
7−text manipulation, and \tTC{Ptr} which represents foreign pointers.
8−There are also several data types declared in the library, including
9−\tTC{Bool}, with values \tDC{True} and \tDC{False}.
10−We can declare some constants with these types. Enter the following
11−into a file \texttt{prims.idr} and load it into the \Idris{} interactive
12−environment by typing \texttt{idris prims.idr}:
13−
14−\begin{code}
15−module prims
16−
17−x : Int
18−x = 42
19−
20−foo : String
21−foo = "Sausage machine"
22−
23−bar : Char
24−bar = 'Z'
25−
26−quux : Bool
27−quux = False
28−\end{code}
29−
30−\noindent
31−An \Idris{} file consists of an optional module declaration (here
32−\texttt{module prims}) followed by an optional list of imports (none here,
33−however \Idris{} programs can consist of several modules, and the definitions
34−in each module each have their own namespace, as we will discuss in Section
35−\ref{sect:namespaces}) and a
36−collection of declarations and definitions. The order of definitions is
37−significant --- functions and data types must be defined before use.
38−Each definition must have a type
39−declaration (here, \texttt{x : Int}, \texttt{foo : String}, etc).
40−Indentation is significant --- a new declaration begins at the same level
41−of indentation as the preceding declaration. Alternatively, declarations
42−may be terminated with a semicolon.
43−
44−A library module \texttt{prelude} is automatically imported by every \Idris{} program,
45−including facilities for IO, arithmetic, data structures and various common
46−functions. The prelude defines several arithmetic and comparison operators,
47−which we can use at the prompt. Evaluating things at the prompt gives an
48−answer, and the type of the answer. For example:
49−
50−\begin{lstlisting}
51−*prims> 6*6+6
52−42 : Int
53−*prims> x == 6*6+6
54−True : Bool
55−\end{lstlisting}
56−
57−\noindent
58−All of the usual arithmetic and comparison operators are defined for the primitive
59−types. They are overloaded using type classes, as we will discuss in Section
60−\ref{sec:classes} and can be extended to work on user defined types.
61−Boolean expressions can be tested with the \texttt{if...then...else} construct:
62−
63−\begin{lstlisting}
64−*prims> if x == 6 * 6 + 6 then "The answer!" else "Not the answer"
65−"The answer!" : String
66−\end{lstlisting}
67−
68−\subsection{Data Types}
69−
70−Data types are declared in a similar way to Haskell data types, with a similar
71−syntax. Natural numbers and lists, for example, can be declared as follows:
72−
73−\begin{code}
74−data Nat = Z | S Nat -- Natural numbers
75− -- (zero and successor)
76−data List a = Nil | (::) a (List a) -- Polymorphic lists
77−\end{code}
78−
79−\noindent
80−The above declarations are taken from the standard library. Unary natural
81−numbers can be either zero (\texttt{Z}), or
82−the successor of another natural number (\texttt{S k}).
83−Lists can either be empty (\texttt{Nil})
84−or a value added to the front of another list (\texttt{x :: xs}).
85−In the declaration for \tTC{List}, we used an infix operator \tDC{::}. New operators
86−such as this can be added using a fixity declaration, as follows:
87−
88−\begin{code}
89−infixr 10 ::
90−\end{code}
91−
92−\noindent
93−Functions, data constructors and type constuctors may all be given infix
94−operators as names. They may be used in prefix form if enclosed in brackets,
95−e.g. \tDC{(::)}. Infix operators can use any of the symbols:
96−
97−\begin{lstlisting}
98−:+-*/=_.?|&><!@$%^~.
99−\end{lstlisting}
100−
101−\subsection{Functions}
102−
103−Functions are implemented by pattern matching, again using a similar syntax to
104−Haskell. The main difference is that \Idris{} requires type declarations for all
105−functions, using a single colon \texttt{:} (rather than
106−Haskell's double colon \texttt{::}). Some natural number arithmetic functions can be
107−defined as follows, again taken from the standard library:
108−
109−\begin{code}
110−-- Unary addition
111−plus : Nat -> Nat -> Nat
112−plus Z y = y
113−plus (S k) y = S (plus k y)
114−
115−-- Unary multiplication
116−mult : Nat -> Nat -> Nat
117−mult Z y = Z
118−mult (S k) y = plus y (mult k y)
119−\end{code}
120−
121−\noindent
122−The standard arithmetic operators \texttt{+} and \texttt{*} are also overloaded
123−for use by \texttt{Nat}, and are implemented
124−using the above functions. Unlike Haskell, there is no restriction on whether
125−types and function names must begin with a capital letter or not. Function
126−names (\tFN{plus} and \tFN{mult} above), data constructors (\tDC{Z}, \tDC{S},
127−\tDC{Nil} and \tDC{::}) and type constructors (\tTC{Nat} and \tTC{List}) are
128−all part of the same namespace.
129−
130−We can test these functions at the \Idris{} prompt:
131−
132−\begin{lstlisting}
133−Idris> plus (S (S Z)) (S (S Z))
134−S (S (S (S Z))) : Nat
135−Idris> mult (S (S (S Z))) (plus (S (S Z)) (S (S Z)))
136−S (S (S (S (S (S (S (S (S (S (S (S Z))))))))))) : Nat
137−\end{lstlisting}
138−
139−\noindent
140−Like arithmetic operations, integer literals are also overloaded using type classes,
141−meaning that we can also test the functions as follows:
142−
143−\begin{lstlisting}
144−Idris> plus 2 2
145−S (S (S (S Z))) : Nat
146−Idris> mult 3 (plus 2 2)
147−S (S (S (S (S (S (S (S (S (S (S (S Z))))))))))) : Nat
148−\end{lstlisting}
149−
150−\noindent
151−You may wonder, by the way, why we have unary natural numbers when our
152−computers have perfectly good integer arithmetic built in. The reason is
153−primarily that unary numbers have a very convenient structure which is easy to
154−reason about, and easy to relate to other data structures as we will see later.
155−Nevertheless, we do not want this convenience to be at the expense of
156−efficiency. Fortunately, \Idris{} knows about the relationship between
157−\tTC{Nat} (and similarly structured types) and numbers, so optimises the
158−representation and functions such as \tFN{plus} and \tFN{mult}.
159−
160−\subsubsection*{\texttt{where} clauses}
161−
162−Functions can also be defined \emph{locally} using \texttt{where} clauses. For example,
163−to define a function which reverses a list, we can use an auxiliary function which
164−accumulates the new, reversed list, and which does not need to be visible globally:
165−
166−\begin{code}
167−reverse : List a -> List a
168−reverse xs = revAcc [] xs where
169− revAcc : List a -> List a -> List a
170− revAcc acc [] = acc
171− revAcc acc (x :: xs) = revAcc (x :: acc) xs
172−\end{code}
173−
174−\noindent
175−Indentation is significant --- functions in the \texttt{where} block must be indented
176−further than the outer function.
177−
178−\textbf{Scope:}
179−Any names which are visible in the outer scope are also visible in the
180−\texttt{where} clause (unless they have been redefined, such as \texttt{xs}
181−here). A name which appears only in the type will be in scope in the
182−\texttt{where} clause if it is a \remph{parameter} to one of the types,
183−i.e. it is fixed across the entire structure.
184−
185−As well as functions, \texttt{where} blocks can include local data
186−declarations, such as the following where \texttt{MyLT} is not accessible outside
187−the definition of \texttt{foo}:
188−
189−\begin{code}
190−foo : Int -> Int
191−foo x = case isLT of
192− Yes => x*2
193− No => x*4
194− where
195− data MyLT = Yes | No
196−
197− isLT : MyLT
198− isLT = if x < 20 then Yes else No
199−\end{code}
200−
201−\noindent
202−In general, functions defined in a \texttt{where} clause need a type declaration
203−just like any top level function. However, the type declaration for
204−a function \texttt{f} \remph{can} be omitted if:
205−
206−\begin{itemize}
207−\item \texttt{f} appears in the right hand side of the top level definition
208−\item The type of \texttt{f} can be completely determined from its first
209−application
210−\end{itemize}
211−
212−\noindent
213−So, for example, the following definitions are legal:
214−
215−\begin{code}
216−even : Nat -> Bool
217−even Z = True
218−even (S k) = odd k where
219− odd Z = False
220− odd (S k) = even k
221−
222−test : List Nat
223−test = [c (S 1), c Z, d (S Z)]
224− where c x = 42 + x
225− d y = c (y + 1 + z y)
226− where z w = y + w
227−\end{code}
228−
229−\subsection{Dependent Types}
230−
231−\subsubsection{Vectors}
232−
233−A standard example of a dependent type is the type of ``lists with length'',
234−conventionally called vectors in the dependent type literature. In \Idris{},
235−we declare vectors as follows\footnote{Note that prior to \Idris{} 0.9.9,
236−the order of the arguments to \texttt{Vect} was reversed.}:
237−
238−\begin{code}
239−data Vect : Nat -> Type -> Type where
240− Nil : Vect Z a
241− (::) : a -> Vect k a -> Vect (S k) a
242−\end{code}
243−
244−\noindent
245−Note that we have used the same constructor names as for \tTC{List}. Ad-hoc
246−name overloading such as this is accepted by \Idris{}, provided that the names
247−are declared in different namespaces (in practice, normally in different modules).
248−Ambiguous constructor names can normally be resolved from context.
249−
250−This declares a family of types, and so the form of the declaration is rather
251−different from the simple type declarations above. We explicitly state the type
252−of the type constructor \tTC{Vect} --- it takes a \tTC{Nat} and a type as an
253−argument, where \tTC{Type} stands for the type of types. We say that \tTC{Vect}
254−is \emph{indexed} over \tTC{Nat} and \emph{parameterised} by \tTC{Type}. Each
255−constructor targets a different part of the family of types. \tDC{Nil} can only
256−be used to construct vectors with zero length, and \tDC{::} to construct
257−vectors with non-zero length. In the type of \tDC{::}, we state explicitly that an element
258−of type \texttt{a} and a tail of type \texttt{Vect k a} (i.e., a vector of length \texttt{k})
259−combine to make a vector of length \texttt{S k}.
260−
261−We can define functions on dependent types such as \tTC{Vect} in the same way
262−as on simple types such as \tTC{List} and \tTC{Nat} above, by pattern matching.
263−The type of a function over \tTC{Vect} will describe what happens to the
264−lengths of the vectors involved. For example, \tFN{++}, defined in the
265−library, appends two \tTC{Vect}s:
266−
267−\begin{code}
268−(++) : Vect n a -> Vect m a -> Vect (n + m) a
269−(++) Nil ys = ys
270−(++) (x :: xs) ys = x :: xs ++ ys
271−\end{code}
272−
273−\noindent
274−The type of \tFN{(++)} states that the resulting vector's length will be the sum of
275−the input lengths. If we get the definition wrong in such a way that this does
276−not hold, \Idris{} will not accept the definition. For example:
277−
278−\begin{code}
279−(++) : Vect n a -> Vect m a -> Vect (n + m) a
280−(++) Nil ys = ys
281−(++) (x :: xs) ys = x :: xs ++ xs -- BROKEN
282−\end{code}
283−
284−\begin{lstlisting}
285−$ idris vbroken.idr --check
286−vbroken.idr:3:Can't unify Vect n a with Vect m a
287−
288−Specifically:
289− Can't unify n with m
290−\end{lstlisting}
291−
292−
293−\noindent
294−This error message suggests that there is a length mismatch between two vectors
295−--- we needed a vector of length \texttt{m}, but provided a vector
296−of length \texttt{n}.
297−%Note that the terms in the error message have been \emph{normalised}, so in
298−%particular \texttt{n + m} has been reduced to \texttt{plus n m}.
299−
300−\subsubsection{The Finite Sets}
301−
302−Finite sets, as the name suggests, are sets with a finite number of elements.
303−They are declared as follows (again, in the prelude):
304−
305−\begin{code}
306−data Fin : Nat -> Type where
307− fZ : Fin (S k)
308− fS : Fin k -> Fin (S k)
309−\end{code}
310−
311−\noindent
312−\tDC{fZ} is the zeroth element of a finite set with \texttt{S k} elements;
313−\texttt{fS n} is the
314−\texttt{n+1}th element of a finite set with \texttt{S k} elements.
315−\tTC{Fin} is indexed by a \tTC{Nat}, which
316−represents the number of elements in the set. Obviously we can't construct an
317−element of an empty set, so neither constructor targets \texttt{Fin Z}.
318−
319−A useful application of the \tTC{Fin} family is to represent bounded
320−natural numbers. Since the first \tTC{n} natural numbers form a finite
321−set of \tTC{n} elements, we can treat \tTC{Fin n} as the set of natural
322−numbers bounded by \tTC{n}.
323−
324−For example, the following function which looks up an element in a \tTC{Vect},
325−by a bounded index given as a \tTC{Fin n}, is defined in the prelude:
326−
327−\begin{code}
328−index : Fin n -> Vect n a -> a
329−index fZ (x :: xs) = x
330−index (fS k) (x :: xs) = index k xs
331−\end{code}
332−
333−\noindent
334−This function looks up a value at a given location in a vector. The location is
335−bounded by the length of the vector (\texttt{n} in each case), so there is no
336−need for a run-time bounds check. The type checker guarantees that the location
337−is no larger than the length of the vector.
338−
339−Note also that there is no case for \texttt{Nil} here. This is because it is
340−impossible. Since there is no element of \texttt{Fin Z}, and the location is a
341−\texttt{Fin n}, then \texttt{n} can not be \tDC{Z}. As a result, attempting to
342−look up an element in an empty vector would give a compile time type error,
343−since it would force \texttt{n} to be \tDC{Z}.
344−
345−\subsubsection{Implicit Arguments}
346−
347−Let us take a closer look at the type of \texttt{index}:
348−
349−\begin{code}
350−index : Fin n -> Vect n a -> a
351−\end{code}
352−
353−\noindent
354−It takes two arguments, an element of the finite set of \texttt{n} elements, and a vector
355−with \texttt{n} elements of type \texttt{a}. But there are also two names,
356−\texttt{n} and \texttt{a}, which are not declared explictly. These are \emph{implicit}
357−arguments to \texttt{index}. We could also write the type of \texttt{index} as:
358−
359−\begin{code}
360−index : {a:Type} -> {n:Nat} -> Fin n -> Vect n a -> a
361−\end{code}
362−
363−\noindent
364−Implicit arguments, given in braces \texttt{\{\}} in the type declaration, are
365−not given in applications of \texttt{index}; their values can be inferred from
366−the types of the \texttt{Fin n} and \texttt{Vect n a} arguments. Any name
367−with a \remph{lower case initial letter} which
368−appears as a parameter or index in a type declaration, but which is otherwise
369−free, will be automatically bound as an implicit argument. Implicit arguments
370−can still be given explicitly in applications, using \texttt{\{a=value\}} and
371−\texttt{\{n=value\}}, for example:
372−
373−\begin{code}
374−index {a=Int} {n=2} fZ (2 :: 3 :: Nil)
375−\end{code}
376−
377−\noindent
378−In fact, any argument, implicit or explicit, may be given a name. We could have
379−declared the type of \texttt{index} as:
380−
381−\begin{code}
382−index : (i:Fin n) -> (xs:Vect n a) -> a
383−\end{code}
384−
385−\noindent
386−It is a matter of taste whether you want to do this --- sometimes it can help
387−document a function by making the purpose of an argument more clear.
388−
389−\subsubsection{``\texttt{using}'' notation}
390−
391−Sometimes it is necessary to provide types of implicit arguments where
392−the type checker can not work them out itself. This can happen if there is a
393−dependency ordering --- obviously, \texttt{a} and \texttt{n} must be given as arguments above
394−before being used --- or if an implicit argument has a complex type. For example,
395−we will need to state the types of the implicit arguments in the following
396−definition, which defines a predicate on vectors:
397−
398−\begin{code}
399−data Elem : a -> Vect n a -> Type where
400− here : {x:a} -> {xs:Vect n a} -> Elem x (x :: xs)
401− there : {x,y:a} -> {xs:Vect n a} -> Elem x xs -> Elem x (y :: xs)
402−\end{code}
403−
404−\noindent
405−An instance of \texttt{Elem x xs} states that \texttt{x} is an element of
406−\texttt{xs}. We can construct
407−such a predicate if the required element is \texttt{here}, at the head of the vector,
408−or \texttt{there}, in the tail of the vector. For example:
409−
410−\begin{code}
411−testVec : Vect 4 Int
412−testVec = 3 :: 4 :: 5 :: 6 :: Nil
413−
414−inVect : Elem 5 testVec
415−inVect = there (there here)
416−\end{code}
417−
418−\noindent
419−If the same implicit arguments are being used a lot, it can make a definition
420−difficult to read. To avoid this problem, a \texttt{using} block gives the types and
421−ordering of any implicit arguments which can appear within the block:
422−
423−\begin{code}
424−using (x:a, y:a, xs:Vect n a)
425− data Elem : a -> Vect n a -> Type where
426− here : Elem x (x :: xs)
427− there : Elem x xs -> Elem x (y :: xs)
428−\end{code}
429−
430−
431−\subsubsection*{Note: Declaration Order and \texttt{mutual} blocks}
432−
433−In general, functions and data types must be defined before use, since
434−dependent types allow functions to appear as part of types, and their
435−reduction behaviour to affect type checking. However, this
436−restriction can be relaxed by using a \texttt{mutual} block, which allows
437−data types and functions to be defined simultaneously:
438−
439−\begin{code}
440−mutual
441− even : Nat -> Bool
442− even Z = True
443− even (S k) = odd k
444−
445− odd : Nat -> Bool
446− odd Z = False
447− odd (S k) = even k
448−\end{code}
449−
450−
451−\noindent
452−In a \texttt{mutual} block, first all of the type declarations are added,
453−then the function bodies. As a result, none of the function types can depend
454−on the reduction behaviour of any of the functions in the block.
455−
456−\subsection{I/O}
457−
458−Computer programs are of little use if they do not interact with the user or
459−the system in some way. The difficulty in a pure language such as \Idris{} ---
460−that is, a language where expressions do not have side-effects --- is that I/O
461−is inherently side-effecting. Therefore in \Idris{}, such interactions are
462−encapsulated in the type \texttt{IO}:
463−
464−\begin{code}
465−data IO a -- IO operation returning a value of type a
466−\end{code}
467−
468−
469−\noindent
470−We'll leave the definition of \texttt{IO} abstract, but effectively it describes what
471−the I/O operations to be executed are, rather than how to execute them. The
472−resulting operations are executed externally,
473−by the run-time system. We've already seen one IO
474−program:
475−
476−\begin{code}
477−main : IO ()
478−main = putStrLn "Hello world"
479−\end{code}
480−
481−
482−\noindent
483−The type of \texttt{putStrLn} explains that it takes a string, and returns an
484−element of the unit type () via an I/O action. There is a variant \texttt{putStr} which
485−outputs a string without a newline:
486−
487−\begin{code}
488−putStrLn : String -> IO ()
489−putStr : String -> IO ()
490−\end{code}
491−
492−We can also read strings from user input:
493−
494−\begin{code}
495−getLine : IO String
496−\end{code}
497−
498−
499−\noindent
500−A number of other I/O operations are defined in the prelude, for example for reading and
501−writing files, including:
502−
503−\begin{code}
504−data File -- abstract
505−data Mode = Read | Write | ReadWrite
506−
507−openFile : String -> Mode -> IO File
508−closeFile : File -> IO ()
509−
510−fread : File -> IO String
511−fwrite : File -> String -> IO ()
512−feof : File -> IO Bool
513−
514−readFile : String -> IO String
515−\end{code}
516−
517−
518−\subsection{``\texttt{do}'' notation}
519−
520−\label{sect:do}
521−
522−I/O programs will typically need to sequence actions, feeding the output of one
523−computation into the input of the next. \texttt{IO} is an abstract type, however, so we
524−can't access the result of a computation directly. Instead, we sequence
525−operations with \texttt{do} notation:
526−
527−\begin{code}
528−greet : IO ()
529−greet = do putStr "What is your name? "
530− name <- getLine
531− putStrLn ("Hello " ++ name)
532−\end{code}
533−
534−
535−\noindent
536−The syntax \texttt{x <- iovalue} executes the I/O operation \texttt{iovalue}, of type
537−\texttt{IO a}, and
538−puts the result, of type \texttt{a} into the variable \texttt{x}.
539−In this case, \texttt{getLine} returns an \texttt{IO String},
540−so \texttt{name} has type \texttt{String}. Indentation is significant --- each
541−statement in the do block must begin in the same column.
542−The \texttt{return} operation allows us to inject a value directly into an IO
543−operation:
544−
545−\begin{code}
546−return : a -> IO a
547−\end{code}
548−
549−
550−\noindent
551−As we will see later, \texttt{do} notation is more general than this, and can be
552−overloaded.
553−
554−\subsection{Useful Data Types}
555−
556−\Idris{} includes a number of useful data types and library functions (see the
557−\texttt{lib/} directory in the distribution). This chapter describes a few of these. The
558−functions described here are imported automatically by every \Idris{} program, as
559−part of \texttt{prelude.idr}.
560−
561−\subsubsection{\texttt{List} and \texttt{Vect}}
562−
563−We have already seen the \texttt{List} and \texttt{Vect} data types:
564−
565−\begin{code}
566−data List a = Nil | (::) a (List a)
567−
568−data Vect : Nat -> Type -> Type where
569− Nil : Vect Z a
570− (::) : a -> Vect k a -> Vect (S k) a
571−\end{code}
572−
573−
574−\noindent
575−Note that the constructor names are the same for each --- constructor names (in
576−fact, names in general) can be overloaded, provided that they are declared in
577−different namespaces (see Section \ref{sect:namespaces}), and will typically be
578−resolved according to their type. As syntactic sugar, any type with the constructor
579−names \texttt{Nil} and \texttt{::} can be written in list form. For example:
580−
581−\begin{itemize}
582−\item \texttt{[]} means \texttt{Nil}
583−\item \texttt{[1,2,3]} means \texttt{1 :: 2 :: 3 :: Nil}
584−\end{itemize}
585−
586−\noindent
587−The library also defines a number of functions for manipulating these types.
588−\texttt{map} is overloaded both for \texttt{List} and \texttt{Vect}
589−and applies a function to every element of the list or vector.
590−
591−\begin{code}
592−map : (a -> b) -> List a -> List b
593−map f [] = []
594−map f (x :: xs) = f x :: map f xs
595−
596−map : (a -> b) -> Vect n a -> Vect n b
597−map f [] = []
598−map f (x :: xs) = f x :: map f xs
599−\end{code}
600−
601−
602−\noindent
603−For example, to double every element in a vector of integers:
604−
605−\begin{code}
606−intVec : Vect 5 Int
607−intVec = [1, 2, 3, 4, 5]
608−
609−double : Int -> Int
610−double x = x * 2
611−\end{code}
612−
613−
614−\noindent
615−You'll find these examples in \texttt{usefultypes.idr} in the \texttt{examples/} directory:
616−
617−\begin{lstlisting}
618−*usefultypes> show (map double intVec)
619−"[2, 4, 6, 8, 10]" : String
620−\end{lstlisting}
621−
622−
623−\noindent
624−For more details of the functions available on \texttt{List} and \texttt{Vect},
625−look in the library, in \texttt{prelude/list.idr} and \texttt{prelude/vect.idr} respectively.
626−Functions include filtering, appending, reversing, and so on. Also remember
627−that \Idris{} is still in development, so if you don't see the function you
628−need, please feel free to add it and submit a patch!
629−
630−\subsubsection*{Aside: Anonymous functions and operator sections}
631−
632−There are actually neater ways to write the above expression. One way would be
633−to use an anonymous function:
634−
635−\begin{lstlisting}
636−*usefultypes> show (map (\x => x * 2) intVec)
637−"[2, 4, 6, 8, 10]" : String
638−\end{lstlisting}
639−
640−
641−\noindent
642−The notation \texttt{$\backslash$x => val} constructs an anonymous function
643−which takes one argument, \texttt{x} and returns the expression \texttt{val}.
644−Anonymous functions may take several arguments, separated by commas, e.g.
645−\texttt{$\backslash$x, y, z => val}. Arguments may also be given explicit
646−types, e.g. \texttt{$\backslash$x : Int => x * 2}, and can pattern match,
647−e.g. \texttt{$\backslash$ (x, y) => x + y}.
648−We could also use an operator section:
649−
650−\begin{code}
651−*usefultypes> show (map (* 2) intVec)
652−"[2, 4, 6, 8, 10]" : String
653−\end{code}
654−
655−
656−\noindent
657−\texttt{(*2)} is shorthand for a function which multiplies a number by 2. It expands to
658−\texttt{$\backslash$x => x * 2}.
659−Similarly, \texttt{(2*)} would expand to \texttt{$\backslash$x => 2 * x}.
660−
661−\subsubsection{Maybe}
662−
663−\texttt{Maybe} describes an optional value. Either there is a value of the given type,
664−or there isn't:
665−
666−\begin{code}
667−data Maybe a = Just a | Nothing
668−\end{code}
669−
670−
671−\noindent
672−\texttt{Maybe} is one way of giving a type to an operation that may fail. For example,
673−looking something up in a \texttt{List} (rather than a vector) may result in an out of
674−bounds error:
675−
676−\begin{code}
677−list_lookup : Nat -> List a -> Maybe a
678−list_lookup _ Nil = Nothing
679−list_lookup Z (x :: xs) = Just x
680−list_lookup (S k) (x :: xs) = list_lookup k xs
681−\end{code}
682−
683−
684−\noindent
685−The \texttt{maybe} function is used to process values of type \texttt{Maybe},
686−either by applying a function to the value, if there is one, or by providing a default value:
687−
688−\begin{code}
689−maybe : Maybe a -> |(default:b) -> (a -> b) -> b
690−\end{code}
691−
692−
693−\noindent
694−The vertical bar $\mid$ before the default value is a laziness annotation. Normally
695−expressions are evaluated before being passed to a function. This is typically
696−the most efficient behaviour. However, in this case, the default value might
697−not be used and if it is a large expression, evaluating it will be wasteful.
698−The $\mid$ annotation tells the compiler not to evaluate the argument until it is
699−needed.
700−
701−\subsubsection{Tuples and Dependent Pairs}
702−
703−Values can be paired with the following built-in data type:
704−
705−\begin{code}
706−data Pair a b = MkPair a b
707−\end{code}
708−
709−
710−\noindent
711−As syntactic sugar, we can write \texttt{(a, b)} which, according to context,
712−means either \texttt{Pair a b} or \texttt{MkPair a b}.
713−Tuples can contain an arbitrary number of values, represented as nested pairs:
714−
715−\begin{code}
716−fred : (String, Int)
717−fred = ("Fred", 42)
718−
719−jim : (String, Int, String)
720−jim = ("Jim", 25, "Cambridge")
721−\end{code}
722−
723−
724−\subsubsection*{Dependent Pairs}
725−
726−Dependent pairs allow the type of the second element of a pair to depend on
727−the value of the first element:
728−
729−\begin{code}
730−data Exists : (A : Type) -> (P : A -> Type) -> Type where
731− Ex_intro : {P : A -> Type} -> (a : A) -> P a -> Exists A P
732−\end{code}
733−
734−
735−\noindent
736−Again, there is syntactic sugar for this. \texttt{(a : A ** P)} is the type of a pair of
737−A and P, where the name \texttt{a} can occur inside P. \texttt{( a ** p )}
738−constructs a value of this type. For example, we can pair a number with a
739−\texttt{Vect} of a particular length.
740−
741−\begin{code}
742−vec : (n : Nat ** Vect n Int)
743−vec = (2 ** [3, 4])
744−\end{code}
745−
746−
747−\noindent
748−The type checker could of course infer the value of the first element from the
749−length of the vector. We can write an underscore \texttt{\_} in place of values which we
750−expect the type checker to fill in, so the above definition could also be
751−written as:
752−
753−\begin{code}
754−vec : (n : Nat ** Vect n Int)
755−vec = (_ ** [3, 4])
756−\end{code}
757−
758−
759−\noindent
760−We might also prefer to omit the type of the first element of the pair, since,
761−again, it can be inferred:
762−
763−\begin{code}
764−vec : (n ** Vect n Int)
765−vec = (_ ** [3, 4])
766−\end{code}
767−
768−
769−\noindent
770−One use for dependent pairs is to return values of dependent types where the
771−index is not necessarily known in advance. For example, if we filter elements
772−out of a \texttt{Vect} according to some predicate, we will not know in advance what the
773−length of the resulting vector will be:
774−
775−\begin{code}
776−filter : (a -> Bool) -> Vect n a -> (p ** Vect p a)
777−\end{code}
778−
779−
780−\noindent
781−If the \texttt{Vect} is empty, the result is easy:
782−
783−\begin{code}
784−filter p Nil = (_ ** [])
785−\end{code}
786−
787−
788−\noindent
789−In the \texttt{::} case, we need to inspect the result of a recursive call to
790−\texttt{filter} to
791−extract the length and the vector from the result. To do this, we use \texttt{with}
792−notation, which allows pattern matching on intermediate values:
793−
794−\begin{code}
795−filter p (x :: xs) with (filter p xs)
796− | ( _ ** xs' ) = if (p x) then ( _ ** x :: xs' ) else ( _ ** xs' )
797−\end{code}
798−
799−\noindent
800−We will see more on \texttt{with} notation later.
801−
802−\subsection{\texttt{so}}
803−
804−The \texttt{so} data type is a predicate on \texttt{Bool} which guarantees that the
805−value is true:
806−
807−\begin{code}
808−data so : Bool -> Type where
809− oh : so True
810−\end{code}
811−
812−
813−\noindent
814−This is most useful for providing a static guarantee that a dynamic check has been made.
815−For example, we might provide a safe interface to a function which draws a pixel
816−on a graphical display as follows, where \texttt{so (inBounds x y)} guarantees that
817−the point \texttt{(x,y)} is within the bounds of a 640x480 window:
818−
819−\begin{code}
820−inBounds : Int -> Int -> Bool
821−inBounds x y = x >= 0 && x < 640 && y >= 0 && y < 480
822−
823−drawPoint : (x : Int) -> (y : Int) -> so (inBounds x y) -> IO ()
824−drawPoint x y p = unsafeDrawPoint x y
825−\end{code}
826−
827−
828−\subsection{More Expressions}
829−
830−\subsubsection*{\texttt{let} bindings}
831−
832−Intermediate values can be calculated using \texttt{let} bindings:
833−
834−\begin{code}
835−mirror : List a -> List a
836−mirror xs = let xs' = rev xs in
837− xs ++ xs'
838−\end{code}
839−
840−
841−\noindent
842−We can do simple pattern matching in \texttt{let} bindings too. For example, we can extract
843−fields from a record as follows, as well as by pattern matching at the top level:
844−
845−\begin{code}
846−data Person = MkPerson String Int
847−
848−showPerson : Person -> String
849−showPerson p = let MkPerson name age = p in
850− name ++ " is " ++ show age ++ " years old"
851−\end{code}
852−
853−
854−\subsubsection*{List comprehensions}
855−
856−\label{sec:listcomp}
857−
858−\Idris{} provides \emph{comprehension} notation as a convenient shorthand for
859−building lists. The general form is:
860−
861−\begin{lstlisting}
862−[ expression | qualifiers ]
863−\end{lstlisting}
864−
865−
866−\noindent
867−This generates the list of values produced by evaluating the
868−\texttt{expression}, according to the conditions given by the comma separated
869−\texttt{qualifiers}. For example, we can build a list of Pythagorean triples as
870−follows:
871−
872−\begin{code}
873−pythag : Int -> List (Int, Int, Int)
874−pythag n = [ (x, y, z) | z <- [1..n], y <- [1..z], x <- [1..y],
875− x*x + y*y == z*z ]
876−\end{code}
877−
878−
879−\noindent
880−The \texttt{[a..b]} notation is another shorthand which builds a list of
881−numbers between \texttt{a} and \texttt{b}. Alternatively \texttt{[a,b..c]}
882−builds a list of numbers between \texttt{a} and \texttt{c} with the increment
883−specified by the difference between \texttt{a} and \texttt{b}. This works for
884−any numeric type, using the \texttt{count} function from the prelude.
885−
886−\subsubsection*{\texttt{case} expressions}
887−
888−Another way of inspecting intermediate values of \emph{simple} types
889−is to use a \texttt{case} expression.
890−The following function, for example, splits a string into two at a given character:
891−
892−\begin{code}
893−splitAt : Char -> String -> (String, String)
894−splitAt c x = case break (== c) x of
895− (x, y) => (x, strTail y)
896−\end{code}
897−
898−
899−\noindent
900−\texttt{break} is a library function which breaks a string into a pair of strings
901−at the point where the given function returns true. We then deconstruct the
902−pair it returns, and remove the first character of the second string.
903−
904−A \texttt{case} expression can match several cases, for example, to inspect an
905−intermediate value of type \texttt{Maybe a}. Recall \texttt{list\_lookup} which
906−looks up an index in a list, returning \texttt{Nothing} if the index is out
907−of bounds. We can use this to write \texttt{lookup\_default}, which
908−looks up an index and returns a default value if the index is out of bounds:
909−
910−\begin{code}
911−lookup_default : Nat -> List a -> a -> a
912−lookup_default i xs def = case list_lookup i xs of
913− Nothing => def
914− Just x => x
915−\end{code}
916−
917−
918−\noindent
919−If the index is in bounds, we get the value at that index, otherwise we get
920−a default value:
921−
922−\begin{lstlisting}
923−*usefultypes> lookup_default 2 [3,4,5,6] (-1)
924−5 : Int
925−*usefultypes> lookup_default 4 [3,4,5,6] (-1)
926−-1 : Int
927−\end{lstlisting}
928−
929−
930−\noindent
931−\textbf{Restrictions:} The \texttt{case} construct is intended for simple analysis
932−of intermediate expressions to avoid the need to write auxiliary functions, and is
933−also used internally to implement pattern matching \texttt{let} and lambda bindings.
934−It will \emph{only} work if:
935−
936−\begin{itemize}
937−\item Each branch \emph{matches} a value of the same type, and \emph{returns} a
938−value of the same type.
939−\item The type of the result is ``known''. i.e. the type of the expression can be
940−determined \emph{without} type checking the \texttt{case}-expression itself.
941−\end{itemize}
942−
943−\subsection{Dependent Records}
944−
945−\remph{Records} are data types which collect several values (the record's
946−\remph{fields}) together. \Idris{} provides syntax for defining records and
947−automatically generating field access and update functions. For example, we
948−can represent a person's name and age in a record:
949−
950−\begin{code}
951−record Person : Type where
952− MkPerson : (name : String) ->
953− (age : Int) -> Person
954−
955−fred : Person
956−fred = MkPerson "Fred" 30
957−\end{code}
958−
959−
960−\noindent
961−Record declarations are like \texttt{data} declarations, except that they are
962−introduced by the \texttt{record} keyword, and can only have one constructor.
963−The names of the binders in the constructor type (\texttt{name} and \texttt{age})
964−here are the field names, which we can use to access the field values:
965−
966−\begin{lstlisting}
967−*record> name fred
968−"Fred" : String
969−*record> age fred
970−30 : Int
971−*record> :t name
972−name : Person -> String
973−\end{lstlisting}
974−
975−\noindent
976−We can also use the field names to update a record (or, more precisely, produce a
977−new record with the given fields updates).
978−
979−\begin{lstlisting}
980−*record> record { name = "Jim" } fred
981−MkPerson "Jim" 30 : Person
982−*record> record { name = "Jim", age = 20 } fred
983−MkPerson "Jim" 20 : Person
984−\end{lstlisting}
985−
986−\noindent
987−The syntax \texttt{record \{ field = val, ... \}} generates a function which updates
988−the given fields in a record.
989−
990−Records, and fields within records, can have dependent types.
991−Updates are allowed to change the type of a field,
992−provided that the result is well-typed, and the result does not affect the type of
993−the record as a whole. For example:
994−
995−\begin{code}
996−record Class : Type where
997− ClassInfo : (students : Vect n Person) ->
998− (className : String) ->
999− Class
1000−\end{code}
1001−
1002−\noindent
1003−It is safe to update the \texttt{students} field to a vector of a different length
1004−because it will not affect the type of the record:
1005−
1006−\begin{code}
1007−addStudent : Person -> Class -> Class
1008−addStudent p c = record { students = p :: students c } c
1009−\end{code}
1010−
1011−\begin{lstlisting}
1012−*record> addStudent fred (ClassInfo [] "CS")
1013−ClassInfo (prelude.vect.:: (MkPerson "Fred" 30) (prelude.vect.Nil)) "CS"
1014− : Class
1015−\end{lstlisting}
1016−
1017−
tutorial/content/views.texdeleted−96
@@ -1,96 +0,0 @@
1−\section{Views and the ``\texttt{with}'' rule}
2−
3−\subsection{Dependent pattern matching}
4−
5−Since types can depend on values, the form of some arguments can be determined
6−by the value of others. For example, if we were to write down the implicit
7−length arguments to \texttt{(++)}, we'd see that the form of the length argument was
8−determined by whether the vector was empty or not:
9−
10−\begin{code}
11−(++) : Vect n a -> Vect m a -> Vect (n + m) a
12−(++) {n=Z} [] ys = ys
13−(++) {n=S k} (x :: xs) ys = x :: xs ++ ys
14−\end{code}
15−
16−\noindent
17−If \texttt{n} was a successor in the \texttt{[]} case, or zero in the
18−\texttt{::} case, the definition
19−would not be well typed.
20−
21−\subsection{The \texttt{with} rule --- matching intermediate values}
22−
23−Very often, we need to match on the result of an intermediate computation.
24−\Idris{} provides a construct for this, the \texttt{with} rule,
25−inspired by views in \Epigram~\cite{view-left},
26−which takes account of the
27−fact that matching on a value in a dependently typed language can affect what
28−we know about the forms of other values. In its simplest form, the \texttt{with} rule
29−adds another argument to the function being defined, e.g. we have already seen
30−a vector filter function, defined as follows:
31−
32−\begin{code}
33−filter : (a -> Bool) -> Vect n a -> (p ** Vect p a)
34−filter p [] = ( _ ** [] )
35−filter p (x :: xs) with (filter p xs)
36− | ( _ ** xs' ) = if (p x) then ( _ ** x :: xs' ) else ( _ ** xs' )
37−\end{code}
38−
39−\noindent
40−Here, the \texttt{with} clause allows us to deconstruct the result of
41−\texttt{filter p xs}.
42−Effectively, it adds this value as an extra argument, which we place after the
43−vertical bar.
44−
45−If the intermediate computation itself has a dependent type, then the result
46−can affect the forms of other arguments --- we can learn the form of one value by
47−testing another. For example, a \texttt{Nat} is either even or odd. If it's even it will
48−be the sum of two equal \texttt{Nat}s. Otherwise, it is the sum of two equal \texttt{Nat}s
49−plus one:
50−
51−\begin{code}
52−data Parity : Nat -> Type where
53− even : Parity (n + n)
54− odd : Parity (S (n + n))
55−\end{code}
56−
57−\noindent
58−We say \texttt{Parity} is a \emph{view} of \texttt{Nat}.
59−It has a \emph{covering function} which tests whether
60−it is even or odd and constructs the predicate accordingly.
61−
62−\begin{code}
63−parity : (n:Nat) -> Parity n
64−\end{code}
65−
66−\label{sect:nattobin}
67−
68−\noindent
69−We'll come back to the definition of \texttt{parity} shortly. We can use it
70−to write a function which converts a natural number to a list of binary digits
71−(least significant first) as follows, using the \texttt{with} rule:
72−
73−\begin{code}
74−natToBin : Nat -> List Bool
75−natToBin Z = Nil
76−natToBin k with (parity k)
77− natToBin (j + j) | even = False :: natToBin j
78− natToBin (S (j + j)) | odd = True :: natToBin j
79−\end{code}
80−
81−\noindent
82−The value of the result of \texttt{parity k} affects the form of \texttt{k},
83−because the result
84−of \texttt{parity k} depends on \texttt{k}.
85−So, as well as the patterns for the result of the
86−intermediate computation (\texttt{even} and \texttt{odd}) right of the
87−\texttt{$\mid$}, we also write how
88−the results affect the other patterns left of the $\mid$. Note that there is a
89−function in the patterns (\texttt{+}) and repeated occurrences of \texttt{j} ---
90−this is allowed
91−because another argument has determined the form of these patterns.
92−
93−We will return to this function in Section \ref{sect:provisional} to complete
94−the definition of \texttt{parity}.
95−
96−
tutorial/fpmacros.stydeleted−1086
@@ -1,1086 +0,0 @@
1−%% ------------------------------------------- [ Functional Programming Macros ]
2−%% A Package to provide support for functional programming.
3−%%
4−\NeedsTeXFormat{LaTeX2e}[1994/06/01]
5−\ProvidesPackage{fpmacros}[2013/12/17 fpmacros]
6−%% ------------------------------------------------------- [ Required Packages ]
7−\RequirePackage{ifthen}
8−\RequirePackage{amssymb}
9−\RequirePackage{latexsym}
10−\RequirePackage{eepic}
11−\RequirePackage{fancyvrb}
12−%% ----------------------------------------------------- [ Option Delcarations ]
13−\newboolean{useverb}
14−\setboolean{useverb}{true}
15−
16−\DeclareOption{noverb}{%
17− \setboolean{useverb}{false}
18−}
19−
20−\ProcessOptions\relax
21−
22−%% --------------------------------------------------------- [ Inference Rules ]
23−\newlength{\rulevgap}
24−\setlength{\rulevgap}{0.05in}
25−\newlength{\ruleheight}
26−\newlength{\ruledepth}
27−\newsavebox{\rulebox}
28−\newlength{\GapLength}
29−\newcommand{\gap}[1]{\settowidth{\GapLength}{#1} \hspace*{\GapLength}}
30−\newcommand{\dotstep}[2]{\begin{tabular}[b]{@{}c@{}}
31− #1\\$\vdots$\\#2
32− \end{tabular}}
33−\newlength{\fracwid}
34−\newcommand{\dotfrac}[2]{\settowidth{\fracwid}{$\frac{#1}{#2}$}
35− \addtolength{\fracwid}{0.1in}
36− \begin{tabular}[b]{@{}c@{}}
37− $#1$\\
38− \parbox[c][0.02in][t]{\fracwid}{\dotfill} \\
39− $#2$\\
40− \end{tabular}}
41−\newcommand{\Rule}[2]{\savebox{\rulebox}[\width][b] %
42− {\( \frac{\raisebox{0in} {\( #1 \)}} %
43− {\raisebox{-0.03in}{\( #2 \)}} \)} %
44− \settoheight{\ruleheight}{\usebox{\rulebox}} %
45− \addtolength{\ruleheight}{\rulevgap} %
46− \settodepth{\ruledepth}{\usebox{\rulebox}} %
47− \addtolength{\ruledepth}{\rulevgap} %
48− \raisebox{0in}[\ruleheight][\ruledepth] %
49− {\usebox{\rulebox}}}
50−\newcommand{\Case}[2]{\savebox{\rulebox}[\width][b] %
51− {\( \dotfrac{\raisebox{0in} {\( #1 \)}} %
52− {\raisebox{-0.03in}{\( #2 \)}} \)} %
53− \settoheight{\ruleheight}{\usebox{\rulebox}} %
54− \addtolength{\ruleheight}{\rulevgap} %
55− \settodepth{\ruledepth}{\usebox{\rulebox}} %
56− \addtolength{\ruledepth}{\rulevgap} %
57− \raisebox{0in}[\ruleheight][\ruledepth] %
58− {\usebox{\rulebox}}}
59−\newcommand{\Axiom}[1]{\savebox{\rulebox}[\width][b] %
60− {$\frac{}{\raisebox{-0.03in}{$#1$}}$} %
61− \settoheight{\ruleheight}{\usebox{\rulebox}} %
62− \addtolength{\ruleheight}{\rulevgap} %
63− \settodepth{\ruledepth}{\usebox{\rulebox}} %
64− \addtolength{\ruledepth}{\rulevgap} %
65− \raisebox{0in}[\ruleheight][\ruledepth] %
66− {\usebox{\rulebox}}}
67−\newcommand{\RuleSide}[3]{\gap{$#2$} \hspace*{0.1in} %
68− \Rule{#1}{#3} %
69− \hspace*{0.1in}$#2$}
70−\newcommand{\AxiomSide}[2]{\gap{$#1$} \hspace*{0.1in} %
71− \Axiom{#2} %
72− \hspace*{0.1in}$#1$}
73−\newcommand{\RULE}[1]{\textbf{#1}}
74−\newcommand{\hg}{\hspace{0.2in}}
75−
76−\newcommand{\ProofState}
77− [2]{\parbox{10cm}{\AR{\hg\AR{#1}\\\Axiom{\hg#2\hg}}}}
78−
79−%%%%%%%%%%%% TRISTUFF
80−
81−\newcommand{\btr}{
82−\setlength{\unitlength}{0.0005in}
83−\begin{picture}(69,180)(0,12)
84−\blacken\path(57,192)(57,12)(12,102)
85− (57,192)(57,192)
86−\path(57,192)(57,12)(12,102)
87− (57,192)(57,192)
88−\end{picture}
89−}
90−
91−\newcommand{\btl}{
92−\setlength{\unitlength}{0.0005in}
93−\begin{picture}(69,180)(0,12)
94−\blacken\path(12,192)(12,12)(57,102)
95− (12,192)(12,192)\path(12,192)(12,12)(57,102)
96− (12,192)(12,192)
97−\end{picture}
98−}
99−
100−\newcommand{\wtr}{
101−\setlength{\unitlength}{0.0005in}
102−\begin{picture}(69,180)(0,12)
103−%\blacken\path(57,192)(57,12)(12,102)
104−% (57,192)(57,192)
105−\path(57,192)(57,12)(12,102)
106− (57,192)(57,192)
107−\end{picture}
108−}
109−
110−\newcommand{\wtl}{
111−\setlength{\unitlength}{0.0005in}
112−\begin{picture}(69,180)(0,12)
113−%\blacken\path(12,192)(12,12)(57,102)
114−% (12,192)(12,192)
115−\path(12,192)(12,12)(57,102)
116− (12,192)(12,192)
117−\end{picture}
118−}
119−
120−
121−
122−%%%%%%%%%%%% FONTS
123−
124−\newcommand{\TC}[1]{\mathsf{#1}}
125−\newcommand{\DC}[1]{\mathsf{#1}}
126−\newcommand{\VV}[1]{\mathit{#1}}
127−\newcommand{\FN}[1]{\mathbf{#1}}
128−\newcommand{\HFN}[1]{\mathtt{#1}}
129−\newcommand{\RW}[1]{\underline{\textrm{#1}}}
130−\newcommand{\MO}[1]{\mbox{\textsc{#1}}}
131−
132−\newcommand{\tTC}[1]{\texttt{#1}}
133−\newcommand{\tDC}[1]{\texttt{#1}}
134−\newcommand{\tFN}[1]{\texttt{#1}}
135−
136−\newcommand{\HF}[1]{\mathtt{#1}}
137−
138−\newcommand{\MV}[1]{\nhole\mathit{#1}}
139−\newcommand{\Lang}[1]{\mathsf{#1}}
140−\newcommand{\Name}[1]{\mathit{#1}}
141−
142−\newcommand{\demph}[1]{\textbf{#1}}
143−\newcommand{\remph}[1]{\emph{#1}}
144−
145−%%%% Keywords for meta operations
146−\newcommand{\IF}{\;\RW{if}\;\;}
147−\newcommand{\THEN}{\RW{then}}
148−\newcommand{\ELSE}{\RW{else}}
149−\newcommand{\AND}{\RW{and}}
150−\newcommand{\Otherwise}{\RW{otherwise}}
151−\newcommand{\Do}{\RW{do}}
152−\newcommand{\Return}{\RW{return}}
153−
154−\newcommand{\CASE}{\RW{case}}
155−\newcommand{\LET}{\RW{let}}
156−\newcommand{\IN}{\RW{in}}
157−\newcommand{\of}{\RW{of}}
158−
159−\newcommand{\CLASS}{\mathtt{class}}
160−\newcommand{\INSTANCE}{\mathtt{instance}}
161−
162−%%%%%%%%%%%% GROUPING
163−
164−\newcommand{\G}{
165−\setlength{\unitlength}{1pt}
166−\begin{picture}(4,10)(0,0)
167−\path(2,10)(2,-10)
168−\end{picture}
169−}
170−
171−\newcommand{\E}{
172−\setlength{\unitlength}{1pt}
173−\begin{picture}(4,10)(0,0)
174−\path(2,10)(2,-2)(4,-2)
175−\end{picture}
176−}
177−
178−%\newcommand{\C}{
179−%\setlength{\unitlength}{1pt}
180−%\begin{picture}(4,10)(0,0)
181−%\path(4,8)(2,8)(2,-2)(4,-2)
182−%\end{picture}
183−%}
184−
185−\newcommand{\M}{
186−\setlength{\unitlength}{1pt}
187−\begin{picture}(4,10)(0,0)
188−\path(2,10)(2,-2)(6,-2)
189−\end{picture}
190−}
191−
192−\newcommand{\F}{
193−\setlength{\unitlength}{1pt}
194−\begin{picture}(4,10)(0,0)
195−\path(4,8)(2,8)(2,-6)
196−\end{picture}
197−}
198−
199−\newcommand{\K}{
200−\setlength{\unitlength}{1pt}
201−\begin{picture}(4,10)(0,0)
202−\path(0,8)(4,8)
203−\end{picture}
204−}
205−
206−\newcommand{\J}{
207−\setlength{\unitlength}{1pt}
208−\begin{picture}(4,10)(0,0)
209−\path(0,-2)(4,-2)
210−\end{picture}
211−}
212−
213−\newcommand{\W}{
214−\setlength{\unitlength}{1pt}
215−\begin{picture}(4,10)(0,0)
216−\end{picture}
217−}
218−
219−
220−
221−%%%%%%%%%%%% GUBBINS
222−
223−\newcommand{\mathskip}{\medskip}
224−
225−\newcommand{\fbx}[1]{\fbox{$#1$}}
226−\newcommand{\stk}[1]{\begin{array}{c}#1\end{array}}
227−%\newcommand{\DM}[1]{\hg\mbox{$#1$}}
228−\newcommand{\DM}[1]{\mathskip\par\(#1\)\mathskip}
229−\newcommand{\mbx}[1]{\mathskip\par\noindent\(#1\)\mathskip}
230−\newcommand{\AR}[1]{\begin{array}[t]{@{}l}#1\end{array}}
231−\newcommand{\ARt}[1]{\begin{array}[t]{@{}l@{}cl}#1\end{array}}
232−\newcommand{\ARc}[1]{\begin{array}{@{}l}#1\end{array}}
233−\newcommand{\ARd}[1]{\begin{array}[t]{cl}#1\end{array}}
234−\newcommand{\DAR}[1]{\begin{array}{ll}\hg & #1\end{array}}
235−\newcommand{\Dor}{\\ \hg\mid & }
236−\newcommand{\EA}[1]{\begin{array}[t]{r@{}c@{}l}#1\end{array}}
237−\newcommand{\A}{@{\:}c}
238−%\newcommand{\R}{@{\:}r}
239−\newcommand{\CA}{c}
240−\newcommand{\LA}{l}
241−\newcommand{\PAc}[2]{\begin{array}{l#1@{}r@{}l}#2\end{array}}
242−\newcommand{\PA}[2]{\begin{array}[t]{l@{\:}l#1@{}r@{\:}l}#2\end{array}}
243−\newcommand{\DTREE}[3]{\begin{array}[t]{l#1@{}r@{\:}l#2}#3\end{array}}
244−\newcommand{\IDTREE}[2]{%
245− \begin{array}[t]{l@{\:}c@{\:}l@{\:}r@{\:}l#1}#2\end{array}}
246−\newcommand{\IA}[2]
247− {\begin{array}[t]{l@{\:}r@{\:}c@{\:}l@{\:}#1@{\:}r@{\:}l}#2\end{array}}
248−\newcommand{\IAc}[2]
249− {\begin{array}[c]{r@{\:}c@{\:}l@{\:}#1@{}r@{}l}#2\end{array}}
250−\newcommand{\CS}[1]{\left\lfloor\begin{array}{@{}l}#1\end{array}\right.}
251−\newcommand{\BY}[3]{\multicolumn{2}{l}{\;\RW{by}\; #1} \\ %
252− \multicolumn{#2}{l}{\CS{#3}} }
253−\newcommand{\WITH}[3]{\multicolumn{2}{l}{\;\RW{with}\; #1} \\ %
254− \multicolumn{#2}{l}{\CS{#3}} }
255−\newcommand{\WithBy}{\RW{with-by}}
256−\newcommand{\Wb}[1]{\WithBy& #1}
257−\newcommand{\By}[1]{\multicolumn{2}{l}{\Leftarrow #1}}
258−\newcommand{\andby}{\Leftarrow}
259−\newcommand{\MyWith}[1]{\multicolumn{2}{l}{|\;#1}}
260−\newcommand{\Byr}[1]{\;\RW{by}\; #1}
261−
262−\newcommand{\Bar}{|}
263−\newcommand{\Bart}{\settowidth{\GapLength}{$\Bar$}%
264− \raisebox{6pt}[0pt][0pt]{$\Bar$}%
265− \hspace*{-1\GapLength}%
266− \Bar}
267−\newcommand{\With}[1]{\Bar & #1}
268−\newcommand{\Witt}[1]{\Bart & #1}
269−
270−\newcommand{\B}{@{\:}r@{\:}c}
271−\newcommand{\Ret}[1]{\multicolumn{2}{l}{\cq #1}}
272−\newcommand{\MRet}[2]{\multicolumn{#1}{l}{\cq #2}}
273−\newcommand{\HRet}[1]{\multicolumn{2}{l}{\hq #1}}
274−\newcommand{\MHRet}[2]{\multicolumn{#1}{l}{\hq #2}}
275−\newcommand{\IRet}[1]{\multicolumn{2}{l}{\iq #1}}
276−\newcommand{\IMRet}[2]{\multicolumn{#1}{l}{\iq #2}}
277−\newcommand{\MoRet}[1]{\multicolumn{2}{l}{\mq #1}}
278−\newcommand{\MMoRet}[2]{\multicolumn{#1}{l}{\mq #2}}
279−\newcommand{\Data}{\RW{data}}
280−\newcommand{\Codata}{\RW{codata}}
281−\newcommand{\Where}{\RW{where}}
282−\newcommand{\Let}{\RW{let}}
283−\newcommand{\Fact}{\RW{fact}}
284−\newcommand{\Rec}[1]{#1\textbf{-Rec}}
285−\newcommand{\Memo}[1]{#1\textbf{-Memo}}
286−\newcommand{\Elim}[1]{#1\textbf{-Elim}}
287−\newcommand{\Cases}[1]{#1\textbf{-Case}}
288−\newcommand{\View}[1]{#1\textbf{-View}}
289−\newcommand{\As}[2]{#1 \:\RW{as}\: #2}
290−\newcommand{\nhole}{\Box}
291−\newcommand{\turq}{\:\vdash_?\:}
292−\newcommand{\split}{\;\lhd\;}
293−\newcommand{\CType}[2]{\{#1 \split\; #2\}}
294−\newcommand{\CC}[2]{(#1)\:#2}
295−\newcommand{\UP}[2]{#1 | \{#2\}}
296−\newcommand{\Ured}{\:\Downarrow\:}
297−\newcommand{\gdd}{\prec}
298−\newcommand{\HC}[1]{\left<#1\right>}
299−\newcommand{\HT}[2]{\left<#1 \hab #2\right>}
300−
301−\newcommand{\view}{\RW{view}}
302−\newcommand{\ecase}{\RW{case}}
303−\newcommand{\rec}{\RW{rec}}
304−
305−\newcommand{\If}{\mathsf{if}}
306−\newcommand{\Then}{\mathsf{then}}
307−\newcommand{\Else}{\mathsf{else}}
308−\newcommand{\elim}{\RW{elim}}
309−
310−\newcommand{\Payload}{\mathsf{type}}
311−\newcommand{\Any}{\mathsf{Some}}
312−
313−\newcommand{\lbl}[2]{\langle #1 \Hab #2 \rangle}
314−\newcommand{\call}[2]{\RW{call}\:\langle#1\rangle\:#2}
315−\newcommand{\return}[1]{\RW{return}\:#1}
316−
317−\newcommand{\Remark}[1]{\noindent\textbf{Remark:} #1}
318−
319−\newcommand{\DBOX}[2]{\fbox{\parbox{#1}{\textbf{Definition:}#2}}}
320−
321−\ifthenelse{\boolean{useverb}}{%
322− \newcommand{\useverbtb}[1]{\begin{tiny}\BUseVerbatim{#1}\end{tiny}}
323− \newcommand{\useverb}[1]{\BUseVerbatim{#1}}
324− \newcommand{\useverbs}[1]{\begin{small}\BUseVerbatim{#1}\end{small}}
325− \newcommand{\useverbb}[1]{\begin{small}\BUseVerbatim{#1}\end{small}}
326− \newcommand{\codefig}[2]{\begin{figure}[h]\useverb{#1}\caption{#2}\label{#1}\end{figure}}
327− \newcommand{\codefigs}[2]{\begin{figure}[h]\useverbs{#1}\caption{#2}\label{#1}\end{figure}}
328− \newcommand{\codefigt}[2]{\begin{figure}[t]\useverb{#1}\caption{#2}\label{#1}\end{figure}}
329− \newcommand{\codefigb}[2]{\begin{figure}[b]\useverb{#1}\caption{#2}\label{#1}\end{figure}}
330− \newcommand{\codefigtc}[2]{\begin{figure*}[t]\useverb{#1}\caption{#2}\label{#1}\end{figure}}
331−}{}
332−
333−\newcommand{\diagfig}[3]{\begin{figure}[h]\begin{center}\includegraphics[width=#1]{#2}\end{center}
334−\caption{#3}\label{#2}\end{figure}}
335−\newcommand{\diagfigtc}[3]{\begin{figure*}[t]\begin{center}\includegraphics[width=#1]{#2}\end{center}
336−\caption{#3}\label{#2}\end{figure*}}
337−
338−\newcommand{\FIG}[3]{\begin{figure}[h]\DM{#1}\caption{#2}\label{#3}\end{figure}}
339−\newcommand{\FFIG}[3]{\begin{figure}\begin{center}\DM{#1}\end{center}\caption{#2}\label{#3}\end{figure}}
340−\newcommand{\FFIGB}[3]{\begin{figure}[b]\begin{center}\DM{#1}\end{center}\caption{#2}\label{#3}\end{figure}}
341−\newcommand{\FFIGTC}[3]{\begin{figure*}[t]\begin{center}\DM{#1}\end{center}\caption{#2}\label{#3}\end{figure*}}
342−\newcommand{\PFIG}[3]{\begin{figure}[p]\begin{center}\fbox{\DM{#1}}\end{center}\caption{#2}\label{#3}\end{figure}}
343−\newcommand{\CFIG}[3]{\begin{figure}[h]\begin{center}\DM{#1}\end{center}\caption{#2}\label{#3}\end{figure}}
344−
345−\ifthenelse{\boolean{useverb}}{%
346− \newcommand{\VFIG}[3]{\begin{figure}[h]\begin{boxedverbatim}#1\end{boxedverbatim}\caption{#2}\label{#3}\end{figure}}
347−}{}
348−
349−\newcommand{\TFIG}[4]{\begin{figure}[h]\begin{center}\begin{tabular}{#1}#2\end{tabular}\end{center}\caption{#3}\label{#4}\end{figure}}
350−\newcommand{\TFIGTC}[4]{\begin{figure*}[t]\begin{center}\begin{tabular}{#1}#2\end{tabular}\end{center}\caption{#3}\label{#4}\end{figure*}}
351−
352−\newcommand{\RESFIG}[3]{
353−\TFIG{|l|c|c|c|c|c|c|c|c|}{
354−\hline
355− & \multicolumn{4}{c|}{\Naive{} compilation} &
356− \multicolumn{4}{|c|}{Optimised compilation} \\
357−\cline{2-9}
358−\raisebox{1.5ex}[0pt]{Program} & Instrs & Thunks & Cells &
359−Accesses & Instructions & Thunks & Cells & Accesses \\
360−%\raisebox{1.5ex}[0pt]{Program} & I & T & C & M & I & T & C & M \\
361−\hline
362−#1
363−\hline
364−}{#2}{#3}}
365−
366−\newcommand{\NEWRESFIG}[3]{
367−\TFIG{|l|l|c|c|c|c|}{
368−\hline
369−% & \multicolumn{4}{c|}{\Naive{} compilation} &
370−% \multicolumn{4}{|c|}{Optimised compilation} \\
371−%\cline{2-9}
372−Program & Version & Instructions & Thunks & Memory Accesses & Cells \\
373−%\raisebox{1.5ex}[0pt]{Program} & I & T & C & M & I & T & C & M \\
374−\hline
375−#1
376−}{#2}{#3}}
377−
378−\newcommand{\NEWRESFIGTC}[3]{
379−\TFIGTC{|l|l|c|c|c|c|}{
380−\hline
381−% & \multicolumn{4}{c|}{\Naive{} compilation} &
382−% \multicolumn{4}{|c|}{Optimised compilation} \\
383−%\cline{2-9}
384−Program & Version & Instructions & Thunks & Memory Accesses & Cells \\
385−%\raisebox{1.5ex}[0pt]{Program} & I & T & C & M & I & T & C & M \\
386−\hline
387−#1
388−}{#2}{#3}}
389−
390−\newcommand{\RESLINE}[9]{
391−& \Naive{} & #2 & #3 & #5 & #4 \\
392−#1
393−& Optimised & #6 & #7 & #9 & #8 \\
394−}
395−\newcommand{\RESCHANGE}[4]{
396−& Change & \textbf{#1} & \textbf{#2} & \textbf{#4} & \textbf{#3} \\
397−\hline
398−}
399−\newcommand{\RESCHANGEa}[5]{
400−#5 & Change & \textbf{#1} & \textbf{#2} & \textbf{#4} & \textbf{#3} \\
401−\hline
402−}
403−
404−%%%%%%%%%%%% PUNCTUATION
405−
406−\newcommand{\pad}[2]{#1#2#1}
407−
408−\newcommand{\hab}{\pad{\,}{:}}
409−\newcommand{\Hab}{\pad{\;}{:}}
410−\newcommand{\HHab}{\pad{\;}{::}}
411−
412−%%%%%%%%%%%% TYPE
413−
414−\newcommand{\Type}{\mbox{\texttt{\#}}} %\star}
415−
416−
417−%%%%%%%%%%%%% ARROWS
418−
419−\newcommand{\To}{\pad{\:}{\rightarrow}}
420−\newcommand{\Gets}{\leftarrow}
421−%\newcommand{\car}{\vartriangleright}
422−
423−%%%%%%%%%%%%% QUANTIFIERS
424−
425−\newcommand{\lam}[2]{\lambda#1\pad{\!}{:}#2}
426−\newcommand{\fbind}[3]{(#1\Hab#2)\to#3}
427−\newcommand{\all}[2]{\forall#1\pad{\!}{:}#2}
428−\newcommand{\hole}[2]{?#1\pad{\!}{:}#2}
429−\newcommand{\guess}[3]{?#1\pad{\!}{:}#2\approx#3}
430−\newcommand{\remlam}[2]{\lambda\{#1\pad{\!}{:}#2\}}
431−\newcommand{\remall}[2]{\forall\{#1\pad{\!}{:}#2\}}
432−\newcommand{\allpi}[2]{\Pi#1\pad{\!}{:}#2}
433−\newcommand{\ali}[2]{\forall#1|#2}
434−\newcommand{\exi}[2]{\exists#1\pad{\!}{:}#2}
435−\newcommand{\wit}[2]{\ang{#1,#2}}
436−\newcommand{\X}{\times}
437−\newcommand{\sig}[2]{\Sigma#1\pad{\!}{:}#2}
438−
439−\newcommand{\SC}{.\:}
440−
441−\newcommand{\letbind}[3]{\mathsf{let}\:#1{:}#2\:=\:#3\:\mathsf{in}}
442−\newcommand{\ifthen}[3]{\mathsf{if}\:#1\:\mathsf{then}\:#2\:\mathsf{else}\:#3}
443−
444−%%%%%%%%%%%%% EQUALITIES
445−
446−\newcommand{\cq}{\pad{\:}{\mapsto}}
447−\newcommand{\xq}{\pad{}{\doteq}}
448−\newcommand{\pq}{\pad{\:}{=}}
449−\newcommand{\dq}{\pad{\:}{:=}}
450−\newcommand{\iq}{\pad{\:}{\leadsto}}
451−\newcommand{\mq}{\Longrightarrow}
452−\newcommand{\retq}{\Rightarrow}
453−\newcommand{\hq}{\pad{\:}{=}}
454−\newcommand{\defq}{\mapsto}
455−
456−\newcommand{\refl}{\TC{refl}}
457−
458−
459−
460−
461−%%%%%%%%%%%%% CATSTUFF
462−
463−\newlength{\Lwibrs}
464−\newlength{\Lwobrs}
465−\newsavebox{\Bwibrs}
466−\newsavebox{\Bwobrs}
467−\newcommand{\Db}[5]{%
468− \savebox{\Bwobrs}[\width][b]{$#5$}%
469− \savebox{\Bwibrs}[\width][b]{$\left#2\usebox{\Bwobrs}\right#3$}%
470− \settowidth{\Lwobrs}{\usebox{\Bwobrs}}%
471− \settowidth{\Lwibrs}{\usebox{\Bwibrs}}%
472− \addtolength{\Lwibrs}{-\Lwobrs}%
473− \left#1\pad{\hspace*{-0.25\Lwibrs}}{\usebox{\Bwibrs}}\right#4}
474−\newcommand{\LDb}[3]{%
475− \savebox{\Bwobrs}[\width][b]{$#3$}%
476− \savebox{\Bwibrs}[\width][b]{$\left#2\usebox{\Bwobrs}\right.$}%
477− \settowidth{\Lwobrs}{\usebox{\Bwobrs}}%
478− \settowidth{\Lwibrs}{\usebox{\Bwibrs}}%
479− \addtolength{\Lwibrs}{-\Lwobrs}%
480− \left#1\hspace*{-0.4\Lwibrs}\usebox{\Bwibrs}\right.}
481−\newcommand{\RDb}[3]{%
482− \savebox{\Bwobrs}[\width][b]{$#3$}%
483− \savebox{\Bwibrs}[\width][b]{$\left.\usebox{\Bwobrs}\right#1$}%
484− \settowidth{\Lwobrs}{\usebox{\Bwobrs}}%
485− \settowidth{\Lwibrs}{\usebox{\Bwibrs}}%
486− \addtolength{\Lwibrs}{-\Lwobrs}%
487− \left.\usebox{\Bwibrs}\hspace*{-0.4\Lwibrs}\right#2}
488−\newcommand{\Sc}{\Db{[}{[}{]}{]}}
489−\newcommand{\Mo}{\Db{|}{>}{<}{|}}
490−\newcommand{\MoL}{\LDb{|}{>}}
491−\newcommand{\MoR}{\RDb{<}{|}}
492−
493−\newcommand{\car}{\mbox{$-\!\triangleright$}}
494−\newcommand{\io}[1]{\iota_{#1}}
495−\newcommand{\cc}{\diamond}
496−
497−
498−%%%%%%%%%%%%% FNS
499−
500−\newcommand{\Wk}{\Uparrow}
501−
502−%%%%%%%%%%%%% Transformation
503−
504−\newcommand{\Transform}[3]{\textsc{Trans}\:_{\Name{#1}}
505− \interp{#2}\:\mq\:#3}
506−%\:[\:#2\:\Longrightarrow\:#3\:]}
507−\newcommand{\Morphism}[2]{\textsc{Morphism}\:#1\:\Longrightarrow\:#2}
508−\newcommand{\MI}[1]{\begin{array}{ll} #1 \end{array}\\}
509−\newcommand{\MorphItem}[2]{& #1 \:\Longrightarrow\: #2}
510−
511−%%%%%%%%%%%%% Stuff
512−
513−% Motive and methods
514−
515−\newcommand{\motive}{\vP}
516−\newcommand{\meth}[1]{\vm_{#1}}
517−
518−% Tuples
519−\newcommand{\tuple}[1]{\langle#1\rangle}
520−\newcommand{\Tuple}[1]{\mathsf{Tuple}}
521−\newcommand{\proj}{\mathsf{proj}}
522−\newcommand{\app}{\mathrm{+\!+}}
523−
524−% Commenting out
525−\newcommand{\ig}[1]{[#1]}
526−\newcommand{\rem}[1]{\{\!#1\!\}}
527−\newcommand{\igc}[1]{[#1]}
528−\newcommand{\remc}[1]{\{\!#1\!\}}
529−
530−
531−\newcommand{\ind}{\hspace*{0.1cm}}
532−
533−% Content free type
534−\newcommand{\CF}{\TC{CF}}
535−\newcommand{\cf}{\DC{cf}}
536−
537−% Error token
538−\newcommand{\error}{\DC{error}}
539−\newcommand{\fail}{\perp}
540−
541−% Constructor stripping
542−\newcommand{\conarg}[2]{#1!#2}
543−
544−\newcommand{\Vect}{\TC{Vect}}
545−\newcommand{\VectM}{\TC{Vect^-}}
546−\newcommand{\Vnil}{\DC{\epsilon}}
547−\newcommand{\Vcons}{\DC{::}}
548−
549−\newcommand{\Vsnoc}{\DC{::}}
550−
551−\newcommand{\VnilM}{\DC{\epsilon^-}}
552−\newcommand{\VconsM}{\DC{::^-}}
553−
554−\newcommand{\Vnilcase}{\VV{vNilCase}}
555−\newcommand{\Vconscase}{\VV{vConsCase}}
556−
557−\newcommand{\DSigma}{\TC{Sigma}}
558−\newcommand{\Exists}{\DC{Exists}}
559−
560−\newcommand{\ListPair}[2]{\sig{#1}{\List\:\vA}.#2 = \FN{length}\:#1}
561−\newcommand{\lpNilDef}{\lpNil{\FN{refl}\:\Z}}
562−\newcommand{\lpNil}[1]{(\nil\:\vA,#1)}
563−\newcommand{\lpConsDef}[3]{\lpCons{#1}{(\FN{fst\:#2})}{\FN{resp}\:(\FN{snd}\:#2)}}
564−\newcommand{\lpCons}[3]{(\cons\:#1\:#2,#3)}
565−\newcommand{\lp}[2]{(#1, #2)}
566−
567−\newcommand{\VnilTop}{\DC{vNil}^\ast}
568−\newcommand{\VconsTop}{\DC{vCons}^\ast}
569−
570−\newcommand{\VnilBot}{\DC{\epsilon}^-}
571−\newcommand{\VconsBot}{\DC{::}^-}
572−
573−\newcommand{\VectTop}{\TC{Vect}^\ast}
574−\newcommand{\VectBot}{\TC{Vect}^-}
575−
576−\newcommand{\VectDrop}{\FN{vectDropIdx}}
577−\newcommand{\VectRebuild}{\FN{vectRebuild}}
578−
579−\newcommand{\Prop}{\TC{Prop}}
580−\newcommand{\Set}{\TC{Set}}
581−\newcommand{\CoqType}{\TC{Type}}
582−
583−\newcommand{\List}{\TC{List}}
584−\newcommand{\nil}{\DC{nil}}
585−\newcommand{\cons}{\DC{cons}}
586−
587−\newcommand{\Zip}{\TC{Tsil}}
588−\newcommand{\zip}{\FN{tsil}}
589−\newcommand{\zipcons}{\FN{tsilcons}}
590−\newcommand{\snoc}{\DC{Snoc}}
591−\newcommand{\lin}{\DC{Empty}}
592−
593−\newcommand{\BigInt}{\TC{BigInt}}
594−\newcommand{\False}{\TC{False}}
595−\newcommand{\Unit}{\TC{Unit}}
596−\newcommand{\UnitI}{\DC{unit}}
597−
598−\newcommand{\genType}{\TC{X}}
599−\newcommand{\genIndicesDec}{\tb\Hab\tB}
600−\newcommand{\genIndices}{\tb}
601−\newcommand{\genConArgsDec}[1]{\vec{\VV{a_#1}}\Hab\vec{\VV{A_#1}}}
602−\newcommand{\genConArgs}[1]{\vec{\VV{a_#1}}}
603−\newcommand{\genConIndicesDec}[1]{\vec{\VV{b_#1}}\Hab\vec{\VV{B_#1}}}
604−\newcommand{\genConIndices}[1]{\vec{\VV{b_#1}}}
605−\newcommand{\genCon}[1]{\DC{x}_#1}
606−
607−\newcommand{\genTypeTop}{\TC{X^\ast}}
608−\newcommand{\genTypeBot}{\TC{X^-}}
609−
610−\newcommand{\genTypeDrop}{\FN{XDropIdx}}
611−\newcommand{\genTypeRebuild}{\FN{XRebuild}}
612−
613−\newcommand{\HTerm}{\texttt{Term}}
614−\newcommand{\Term}{\TC{Term}}
615−\newcommand{\Var}{\DC{var}}
616−\newcommand{\Lam}{\DC{lam}}
617−\newcommand{\App}{\DC{app}}
618−\newcommand{\TermM}{\TC{Term^-}}
619−\newcommand{\VarM}{\DC{var^-}}
620−\newcommand{\LamM}{\DC{lam^-}}
621−\newcommand{\AppM}{\DC{app^-}}
622−\newcommand{\Env}{\TC{Env}}
623−\newcommand{\SType}{\TC{STy}}
624−\newcommand{\farrow}{\Rightarrow}
625−\newcommand{\lookup}{\FN{lookup}}
626−
627−% \newcommand{\source}{\Lang{TT}}
628−\newcommand{\source}{\textbf{DT-Res}}
629−\newcommand{\target}{\Lang{ExTT}}
630−\newcommand{\runtime}{\Lang{RunTT}}
631−
632−\newcommand{\lt}{\TC{<}}
633−\newcommand{\ltO}{\DC{ltO}}
634−\newcommand{\ltS}{\DC{ltS}}
635−
636−\newcommand{\interp}[1]{\llbracket #1 \rrbracket}
637−\newcommand{\inferrable}[2]{\FN{inferrable}(#1,#2)}
638−\newcommand{\mkPat}{\FN{mkPat}}
639−
640−\newcommand{\FinM}{\TC{Fin^-}}
641−\newcommand{\fzM}{\DC{f0^-}}
642−\newcommand{\fsM}{\DC{fs^-}}
643−
644−\newcommand{\concat}{\mathrm{++}}
645−
646−%\newcommand{\bottom}{\perp}
647−
648−% Reductions
649−
650−\newcommand{\reduces}{\mapsto}
651−\newcommand{\translation}{\Rightarrow}
652−%\newcommand{\reducesn}[1]{\reduces\hspace*{-0.15cm}_{#1}}
653−%\newcommand{\reducesto}{\reduces\hspace*{-0.15cm}^{*}}
654−\newcommand{\reducesn}[1]{\reduces_{#1}}
655−\newcommand{\reducesto}{\reduces^{*}}
656−
657−% Equality
658−
659−\newcommand{\Refl}{\DC{refl}}
660−\newcommand{\leZ}{\DC{O_{\le}}}
661−\newcommand{\leS}{\DC{S_{\le}}}
662−
663−% Random elimination things
664−
665−\newcommand{\lte}{\TC{\leq}}
666−\newcommand{\lten}{\DC{leN}}
667−\newcommand{\lteO}{\DC{leO}}
668−\newcommand{\lteS}{\DC{leS}}
669−
670−\newcommand{\ltelim}{\Elim{\lt}}
671−\newcommand{\leelim}{\Elim{\lte}}
672−
673−\newcommand{\dD}{\TC{D}}
674−\newcommand{\delim}{\Elim{\TC{D}}}
675−\newcommand{\drec}{\Rec{\TC{D}}}
676−\newcommand{\dcase}{\Cases{\TC{D}}}
677−\newcommand{\dview}{\View{\TC{D}}}
678−\newcommand{\dmemo}{\Memo{\TC{D}}}
679−\newcommand{\natrec}{\Rec{\Nat}}
680−\newcommand{\natmemo}{\Memo{\Nat}}
681−\newcommand{\natmemogen}{\Nat\textbf{-MemoGen}}
682−\newcommand{\natelim}{\Elim{\Nat}}
683−\newcommand{\boolcase}{\Cases{\Bool}}
684−\newcommand{\vectrec}{\Rec{\Vect}}
685−\newcommand{\vectelim}{\Elim{\Vect}}
686−\newcommand{\listrec}{\Rec{\List}}
687−\newcommand{\listelim}{\Elim{\List}}
688−\newcommand{\finrec}{\Rec{\Fin}}
689−\newcommand{\finelim}{\Elim{\Fin}}
690−\newcommand{\natcase}{\Cases{\Nat}}
691−\newcommand{\vectcase}{\Cases{\Vect}}
692−\newcommand{\natdoublerec}{\Nat\textbf{-double-elim}}
693−\newcommand{\eqelim}{=\textbf{-elim}}
694−\newcommand{\falsecase}{\Cases{\False}}
695−
696−% Code
697−\ifthenelse{\boolean{useverb}}{%
698− \newcommand{\Haskell}[1]{\begin{quotation}\begin{verbatim}#1\end{verbatim}\end{quotation}}
699−}{}
700−% Quicksort
701−
702−\newcommand{\QSView}{\TC{QuickSort}}
703−\newcommand{\qsempty}{\DC{empty}}
704−\newcommand{\partition}{\DC{partition}}
705−\newcommand{\qsview}{\FN{mkQuickSort}}
706−
707−% More gubbins
708−
709−\newcommand{\converts}{\simeq}
710−\newcommand{\cumul}{\preceq}
711−\newcommand{\whnf}{\Downarrow}
712−\newcommand{\elem}{\in}
713−\newcommand{\proves}{\vdash}
714−\newcommand{\biimplies}{\Longleftrightarrow}
715−
716−\newcommand{\lc}{\lambda_{\mathsf{AC}}}
717−\newcommand{\zed}{\mathbb{Z}}
718−
719−% Haskell keywords
720−
721−\newcommand{\hdata}{\mathtt{data}}
722−\newcommand{\newtype}{\mathtt{newtype}}
723−%\newcommand{\htype}{\mathtt{type}}
724−
725−\newcommand{\HTC}[1]{\mathtt{#1}}
726−\newcommand{\HDC}[1]{\mathtt{#1}}
727−
728−% Nobby
729−
730−\newcommand{\Value}{\HTC{Value}}
731−\newcommand{\VGamma}{\HTC{Env}}
732−\newcommand{\Ctxt}{\HTC{Ctxt}}
733−\newcommand{\Defs}{\HTC{Defs}}
734−\newcommand{\ECtxt}{\HTC{ECtxt}}
735−\newcommand{\TCtxt}{\HTC{TCtxt}}
736−\newcommand{\VG}{\HDC{Env}}
737−\newcommand{\Model}{\HTC{Model}}
738−\newcommand{\Const}{\HTC{Const}}
739−\newcommand{\Normal}{\HTC{Normal}}
740−\newcommand{\Scope}{\HTC{Scope}}
741−\newcommand{\Kripke}{\HTC{Kripke}}
742−\newcommand{\Weakening}{\HTC{Weakening}}
743−\newcommand{\Ready}{\HTC{Ready}}
744−\newcommand{\Blocked}{\HTC{Blocked}}
745−\newcommand{\Spine}{\HTC{Spine}}
746−
747−\newcommand{\BV}{\HDC{BV}}
748−\newcommand{\BCon}{\HDC{BCon}}
749−\newcommand{\BTyCon}{\HDC{BTyCon}}
750−\newcommand{\RCon}{\HDC{RCon}}
751−\newcommand{\RTyCon}{\HDC{RTyCon}}
752−\newcommand{\BElim}{\HDC{BElim}}
753−\newcommand{\DV}{\HDC{V}}
754−\newcommand{\DP}{\HDC{P}}
755−
756−\newcommand{\MR}{\HDC{R}}
757−\newcommand{\MB}{\HDC{B}}
758−\newcommand{\DSc}{\HDC{Sc}}
759−\newcommand{\DKr}{\HDC{Kr}}
760−\newcommand{\DWk}{\HDC{Wk}}
761−\newcommand{\DSnoc}{\HDC{;}}
762−\newcommand{\DType}{\HDC{Type}}
763−\newcommand{\DName}{\HDC{Name}}
764−\newcommand{\DInt}{\HDC{Int}}
765−\newcommand{\DString}{\HDC{String}}
766−\newcommand{\DElim}{\HDC{Elim}}
767−\newcommand{\Empty}{\HDC{\emptyset}}
768−
769−\newcommand{\ConCode}{\HTC{ConCode}}
770−\newcommand{\ElimRule}{\HTC{ElimRule}}
771−
772−\newcommand{\DConst}{\HDC{Const}}
773−\newcommand{\DCon}{\HDC{Con}}
774−\newcommand{\DTyCon}{\HDC{TyCon}}
775−\newcommand{\RConst}{\HDC{RConst}}
776−\newcommand{\RLam}{\HDC{RLam}}
777−\newcommand{\RPi}{\HDC{RPi}}
778−\newcommand{\DLam}{\HDC{Lam}}
779−\newcommand{\DLet}{\HDC{Let}}
780−\newcommand{\DPi}{\HDC{Pi}}
781−\newcommand{\DApp}{\HDC{App}}
782−
783−\newcommand{\TMaybe}{\HTC{Maybe}}
784−\newcommand{\DNothing}{\HDC{Nothing}}
785−\newcommand{\DJust}{\HDC{Just}}
786−
787−
788−% G-machine and heap
789−
790−\newcommand{\PUSH}{\mathsf{PUSH}}
791−\newcommand{\PUSHNAME}{\mathsf{PUSHNAME}}
792−\newcommand{\POP}{\mathsf{DISCARD}}
793−\newcommand{\PUSHFUN}{\mathsf{PUSHFUN}}
794−\newcommand{\APPLY}{\mathsf{MKAP}}
795−\newcommand{\EVAL}{\mathsf{EVAL}}
796−\newcommand{\GCON}{\mathsf{MKCON}}
797−\newcommand{\GTUP}{\mathsf{MKTUP}}
798−\newcommand{\GTYPE}{\mathsf{MKTYPE}}
799−\newcommand{\UPDATE}{\mathsf{UPDATE}}
800−\newcommand{\RET}{\mathsf{RET}}
801−\newcommand{\UNWIND}{\mathsf{UNWIND}}
802−\newcommand{\CASEJUMP}{\mathsf{CASEJUMP}}
803−\newcommand{\LABEL}{\mathsf{LABEL}}
804−\newcommand{\MOVE}{\mathsf{MOVE}}
805−\newcommand{\JUMP}{\mathsf{JUMP}}
806−\newcommand{\SPLIT}{\mathsf{SPLIT}}
807−\newcommand{\SQUEEZE}{\mathsf{SQUEEZE}}
808−\newcommand{\JFUN}{\mathsf{JFUN}}
809−\newcommand{\PROJ}{\mathsf{PROJ}}
810−\newcommand{\ERROR}{\mathsf{ERROR}}
811−\newcommand{\SLIDE}{\mathsf{SLIDE}}
812−\newcommand{\ALLOC}{\mathsf{ALLOC}}
813−
814−\newcommand{\PUSHBIG}{\mathsf{PUSHBIG}}
815−\newcommand{\PUSHBASIC}{\mathsf{PUSHBASIC}}
816−\newcommand{\PUSHINT}{\mathsf{PUSHINT}}
817−\newcommand{\PUSHBOOL}{\mathsf{PUSHBOOL}}
818−\newcommand{\GET}{\mathsf{GET}}
819−\newcommand{\MKINT}{\mathsf{MKINT}}
820−\newcommand{\MKBOOL}{\mathsf{MKBOOL}}
821−\newcommand{\ADD}{\mathsf{ADD}}
822−\newcommand{\SUB}{\mathsf{SUB}}
823−\newcommand{\MULT}{\mathsf{MULT}}
824−\newcommand{\LT}{\mathsf{LT}}
825−\newcommand{\EQ}{\mathsf{EQ}}
826−\newcommand{\GT}{\mathsf{GT}}
827−\newcommand{\JTRUE}{\mathsf{JTRUE}}
828−
829−\newcommand{\APP}{\mathsf{APP}}
830−\newcommand{\FUN}{\mathsf{FUN}}
831−\newcommand{\CON}{\mathsf{CON}}
832−\newcommand{\TYCON}{\mathsf{TYCON}}
833−\newcommand{\TUP}{\mathsf{TUP}}
834−\newcommand{\TYPE}{\mathsf{TYPE}}
835−\newcommand{\INT}{\mathsf{INT}}
836−\newcommand{\BIGINT}{\mathsf{BIGINT}}
837−\newcommand{\BOOL}{\mathsf{BOOL}}
838−\newcommand{\HOLE}{\mathsf{HOLE}}
839−
840−% G machine translation scheme
841−
842−\newcommand{\sinterp}[1]{\mathcal{S}\interp{#1}}
843−\newcommand{\sinterpm}[1]{\mathcal{S}\AR{\interp{#1}}}
844−\newcommand{\einterp}[3]{\mathcal{E}\interp{#1}\:#2\:#3}
845−\newcommand{\cinterp}[3]{\mathcal{C}\interp{#1}\:#2\:#3}
846−\newcommand{\binterp}[3]{\mathcal{B}\interp{#1}\:#2\:#3}
847−\newcommand{\rinterp}[3]{\mathcal{R}\interp{#1}\:#2\:#3}
848−\newcommand{\iinterp}[3]{\mathcal{I}\interp{#1}\:#2\:#3}
849−\newcommand{\len}[1]{\MO{length}(#1)}
850−
851−\newcommand{\casecomp}[2]{\mathcal{I}(#1,\left\{\ARc{#2}\right\})}
852−\newcommand{\casecompA}[3]{\mathcal{I}(#1,\left\{\ARc{#2}\right\}[#3])}
853−\newcommand{\ischeme}{\mathcal{I}}
854−
855−% tail call markup
856−
857−\newcommand{\tailcall}{\mathsf{tail}}
858−
859−% Trees
860−
861−\newcommand{\Tree}{\TC{Tree}}
862−\newcommand{\Leaf}{\DC{Leaf}}
863−\newcommand{\Node}{\DC{Node}}
864−\newcommand{\treecase}{\Cases{\Tree}}
865−
866−% Languages
867−
868−\newcommand{\Coq}{\textsc{Coq}}
869−\newcommand{\Lego}{\textsc{Lego}}
870−\newcommand{\Oleg}{\textsc{Oleg}}
871−\newcommand{\Alf}{\textsc{Alf}}
872−\newcommand{\Epigram}{\textsc{Epigram}}
873−\newcommand{\SystemF}{System $\mathcal{F}$}
874−\newcommand{\Iswim}{\textsc{Iswim}}
875−\newcommand{\Cynthia}{\textit{C$^Y$\hspace*{-0.1cm}NTHIA}}
876−
877−% Accessibility
878−
879−\newcommand{\Acc}{\TC{Acc}}
880−\newcommand{\acc}{\DC{acc}}
881−\newcommand{\qsAcc}{\TC{qsAcc}}
882−\newcommand{\qsNil}{\DC{qsNil}}
883−\newcommand{\qsCons}{\DC{qsCons}}
884−\newcommand{\allQsAcc}{\FN{allQsAcc}}
885−
886−% Lazy shortcuts
887−
888−\newcommand{\naive}{na\"{\i}ve}
889−\newcommand{\Naive}{Na\"{\i}ve}
890−
891−% Conor's bits
892−
893−\newcommand{\remem}[1]{\left|#1\right|}
894−\newcommand{\idsb}{\MO{id}}
895−\newcommand{\ang}[1]{\langle#1\rangle}
896−
897−\newcommand{\vePm}[1]{\vP #1 \vm_{\Vnil} #1 \vm_{\Vcons}}%
898−\newcommand{\vcrhs}{\vm_{\Vcons}\:\vk\:\va\:\vv\:%
899− (\vectelim\:\vA\:\vk\:\vv\:\vePm{\:})}%
900−
901−\newcommand{\igV}[2]{#1^{\ig{#2}}}
902−\newcommand{\remV}[2]{#1^{\rem{#2}}}
903−
904−% More gubbins
905−
906−\newcommand{\Between}{\TC{between}}
907−\newcommand{\bZ}{\DC{bO}}
908−\newcommand{\bZZS}{\DC{bOOs}}
909−\newcommand{\bZSS}{\DC{b0ss}}
910−\newcommand{\bSSS}{\DC{bsss}}
911−\newcommand{\betelim}{\Elim{\Between}}
912−\newcommand{\betrhs}[1]{\motive#1\meth{\bZ}#1\meth{\bZZS}#1\meth{\bZSS}#1\meth{\bSSS}}
913−
914−
915−\newcommand{\valenv}{\TC{ValEnv}}
916−\newcommand{\vempty}{\DC{empty}}
917−\newcommand{\vextend}{\DC{extend}}
918−
919−\newcommand{\EpiVal}{\TC{Epigram}}
920−\newcommand{\unsafeCoerce}{\HF{unsafeCoerce\mbox{\texttt{\#}}}}
921−
922−\newcommand{\qq}{\mbox{\texttt{"}}}
923−\newcommand{\impossible}{\RW{Impossible}}
924−
925−\newcommand{\Real}{\mathbb{R}}
926−
927−\newcommand{\DoubleRec}{\TC{DoubleElim}}
928−\newcommand{\DoubleOn}{\DC{Double_{\Z\vn}}}
929−\newcommand{\DoubleSO}{\DC{Double_{\suc\Z}}}
930−\newcommand{\DoubleSS}{\DC{Double_{\suc\suc}}}
931−
932−\newcommand{\doublerec}{\textbf{double-elim}}
933−
934−\newcommand{\set}{\TC{DList}}
935−\newcommand{\setuser}{\TC{DListTop}}
936−\newcommand{\setempty}{\emptyset}
937−\newcommand{\setinsert}{\DC{insert}}
938−
939−
940−%%%% Type systems
941−
942−\newcommand{\stlc}{\lambda\hspace*{-0.15cm}\to}
943−\newcommand{\plc}{\lambda2}
944−\newcommand{\dlc}{\lambda{}P}
945−
946−\newcommand{\EC}{\mathcal{E}}
947−
948−%%%% reductions
949−
950−\newcommand{\betared}{\iq\hspace*{-0.15cm}_{\beta}}
951−\newcommand{\deltared}{\iq\hspace*{-0.15cm}_{\delta}}
952−\newcommand{\gammared}{\iq\hspace*{-0.15cm}_{\gamma}}
953−\newcommand{\etared}{\iq\hspace*{-0.15cm}_{\eta}}
954−\newcommand{\iotared}{\iq\hspace*{-0.15cm}_{\iota}}
955−\newcommand{\rhored}{\iq\hspace*{-0.15cm}_{\rho}}
956−
957−%%%% ExTT rules
958−
959−\newcommand{\exconverts}{\stackrel{\mathsf{Ex}}{\converts}}
960−\newcommand{\excumul}{\stackrel{\mathsf{Ex}}{\cumul}}
961−\newcommand{\exequiv}{\stackrel{\mathsf{Ex}}{\equiv}}
962−\newcommand{\exreduces}{\stackrel{\mathsf{Ex}}\reduces}
963−\newcommand{\exreducesto}{\stackrel{\mathsf{Ex}}{\reducesto}}
964−\newcommand{\exreducesn}[1]{\exreduces_{#1}}
965−
966−\newcommand{\ttequiv}{\stackrel{\mathsf{TT}}{\equiv}}
967−\newcommand{\ttreduces}{\stackrel{\mathsf{TT}}\reduces}
968−\newcommand{\ttreducesn}[1]{\ttreduces_{#1}}
969−
970−%%% Type synthesis
971−
972−\newcommand{\hastype}{\Longrightarrow}
973−\newcommand{\whnfs}{\twoheadrightarrow}
974−\newcommand{\conv}{\converts}
975−
976−\newcommand{\exhastype}{\stackrel{\mathsf{Ex}}{\hastype}}
977−\newcommand{\exwhnfs}{\stackrel{\mathsf{Ex}}{\whnfs}}
978−\newcommand{\exconv}{\stackrel{\mathsf{Ex}}{\conv}}
979−\newcommand{\exproves}{\stackrel{\mathsf{Ex}}{\proves}}
980−
981−\newcommand{\tthastype}{\stackrel{\mathsf{TT}}{\hastype}}
982−\newcommand{\ttwhnfs}{\stackrel{\mathsf{TT}}{\whnfs}}
983−\newcommand{\ttconv}{\stackrel{\mathsf{TT}}{\conv}}
984−\newcommand{\ttproves}{\stackrel{\mathsf{TT}}{\proves}}
985−
986−%%% Lightning
987−
988−\newcommand{\light}[1]{\lightning^{#1}}
989−\newcommand{\LHab}[1]{\pad{\;}{:^{#1}}}
990−\newcommand{\llam}[3]{\lambda#1\pad{\!}{:}^{#2}#3}
991−\newcommand{\lall}[3]{\forall#1\pad{\!}{:}^{#2}#3}
992−\newcommand{\lapp}[3]{#1(#2)^{#3}}
993−\newcommand{\larg}[2]{(#1)^{#2}}
994−
995−\newcommand{\RName}[1]{\hspace*{0.1in}\mathsf{#1}}
996−
997−%%% LOcal macros
998−
999−\newcommand{\ResState}{\TC{ResourceState}}
1000−\newcommand{\Locked}{\DC{Locked}}
1001−\newcommand{\ResHandle}{\TC{ResourceHandle}}
1002−\newcommand{\Res}{\DC{Resource}}
1003−\newcommand{\CLang}{\TC{CLang}}
1004−\newcommand{\CFLang}{\TC{CFLang}}
1005−\newcommand{\CFType}{\TC{CFType}}
1006−\newcommand{\CLType}{\TC{CType}}
1007−\newcommand{\RHandle}{\DC{RHandle}}
1008−\newcommand{\RType}{\DC{RType}}
1009−\newcommand{\RUnit}{\DC{RUnit}}
1010−\newcommand{\LOCK}{\DC{LOCK}}
1011−\newcommand{\UNLOCK}{\DC{UNLOCK}}
1012−\newcommand{\ACTION}{\DC{ACTION}}
1013−\newcommand{\FORK}{\DC{FORK}}
1014−
1015−\newcommand{\FSLang}{\TC{FSLang}}
1016−\newcommand{\OPEN}{\DC{OPEN}}
1017−\newcommand{\CLOSE}{\DC{CLOSE}}
1018−\newcommand{\READ}{\DC{READ}}
1019−\newcommand{\WRITE}{\DC{WRITE}}
1020−\newcommand{\PRINT}{\DC{PRINT}}
1021−\newcommand{\BIND}{\DC{BIND}}
1022−
1023−\newcommand{\FSType}{\TC{FSType}}
1024−\newcommand{\FHandle}{\DC{FHandle}}
1025−\newcommand{\FString}{\DC{FString}}
1026−\newcommand{\FUnit}{\DC{FUnit}}
1027−\newcommand{\ElemIs}{\TC{ElemIs}}
1028−\newcommand{\elemHd}{\TC{atHead}}
1029−\newcommand{\elemTl}{\TC{inTail}}
1030−
1031−\newcommand{\emptyEnv}{\DC{empty}}
1032−\newcommand{\extendEnv}{\DC{extend}}
1033−
1034−\newcommand{\usera}{\FN{Alice}}
1035−\newcommand{\userb}{\FN{Bob}}
1036−\newcommand{\userc}{\FN{Charlie}}
1037−
1038−\newcommand{\FAcc}{\TC{FAcc}}
1039−\newcommand{\UserA}{\DC{UserAcc}}
1040−\newcommand{\GroupA}{\DC{GroupAcc}}
1041−\newcommand{\GlobalA}{\DC{GlobalAcc}}
1042−
1043−\newcommand{\Perm}{\TC{Perm}}
1044−\newcommand{\Username}{\TC{Username}}
1045−\newcommand{\GroupData}{\TC{GroupData}}
1046−\newcommand{\File}{\TC{File}}
1047−\newcommand{\FS}{\DC{file}}
1048−\newcommand{\Filepath}{\TC{Filepath}}
1049−
1050−\newcommand{\Read}{\DC{Read}}
1051−\newcommand{\Write}{\DC{Write}}
1052−\newcommand{\Execute}{\DC{Execute}}
1053−
1054−\newcommand{\Purpose}{\TC{Mode}}
1055−\newcommand{\Reading}{\DC{Reading}}
1056−\newcommand{\Writing}{\DC{Writing}}
1057−
1058−\newcommand{\FileState}{\TC{FileState}}
1059−\newcommand{\FileHandle}{\TC{FileHandle}}
1060−\newcommand{\OpenH}{\DC{OpenH}}
1061−\newcommand{\ClosedH}{\DC{ClosedH}}
1062−\newcommand{\Handle}{\TC{Handle}}
1063−\newcommand{\Open}{\DC{Open}}
1064−\newcommand{\Closed}{\DC{Closed}}
1065−
1066−\newcommand{\UserIO}{\TC{UserIO}}
1067−\newcommand{\uio}{\DC{uio}}
1068−
1069−\newcommand{\CFS}{\TC{C_{fs}}}
1070−\newcommand{\RFS}{\FN{R_{fs}}}
1071−
1072−\newcommand{\String}{\TC{String}}
1073−
1074−% inline idris code
1075−
1076−\newcommand{\Tcon}[1]{\texttt{#1}}
1077−\newcommand{\Dcon}[1]{\texttt{#1}}
1078−\newcommand{\Fname}[1]{\texttt{#1}}
1079−\newcommand{\Vv}[1]{\texttt{#1}}
1080−\newcommand{\TyTy}{\texttt{\#}}
1081−
1082−\newcommand{\direct}[1]{\texttt{\%#1}}
1083−
1084−\newcommand{\Feature}[1]{\textbf{Remark:}}
1085−
1086−\endinput
tutorial/idris-tutorial.texdeleted−56
@@ -1,56 +0,0 @@
1−\documentclass[british, final]{article}
2−
3−\usepackage[l2tabu,orthodox]{nag}
4−\usepackage{fixltx2e}
5−\usepackage{babel}
6−\usepackage[iso]{isodate}
7−\usepackage[utf8]{inputenc}
8−\usepackage[T1]{fontenc}
9−\usepackage[protrusion=true, expansion=true]{microtype}
10−\usepackage[strict=true]{csquotes}
11−\usepackage{xspace}
12−
13−\usepackage{mathpazo}
14−\usepackage[scaled=0.95]{helvet}
15−\usepackage{courier}
16−
17−\usepackage{fullpage}
18−\usepackage{hyperref}
19−\usepackage[missing=0.9.10]{gitinfo}
20−
21−\usepackage{fpmacros}
22−\usepackage[numbers]{idrislang}
23−
24−\input{conf.ltx}
25−\input{library.ltx}
26−
27−\newcommand{\version}{\gitVtagn}
28−
29−\title{Programming in \Idris{}: a tutorial}
30−\author{The \Idris{} Community}
31−\date{\origdate\today}
32−
33−\begin{document}
34−
35−\maketitle
36−
37−\tableofcontents
38−\newpage
39−
40−\input{./content/intro}
41−\input{./content/starting}
42−\input{./content/typesfuns}
43−\input{./content/classes}
44−\input{./content/modules}
45−\input{./content/interp}
46−\input{./content/views}
47−\input{./content/theorems}
48−\input{./content/provisional}
49−\input{./content/syntax}
50−\input{./content/miscellany}
51−\input{./content/conclusions}
52−
53−\bibliographystyle{abbrv}
54−\bibliography{literature.bib}
55−
56−\end{document}
tutorial/idrislang.stydeleted−190
@@ -1,190 +0,0 @@
1−%% --------------------------------------------------- [ Idris Styling Package ]
2−%%
3−%% A set of LaTeX macros and styling for working with Idris in LaTeX
4−%%
5−%% + Provides a listings bindings:
6−%% + idris :: default ascii
7−%% + literateidris :: convert ascii maths to math symbols.
8−%% + Defines a `numbers' and `default' listings style.
9−%% + Defines a `code' environment for typesetting idris.
10−%% + \begin{code}[...] ... \end{code}
11−%% + Defines commands typesetting the name Idris.
12−%% + \Idris{}
13−%% + \idris{}
14−%%
15−%% Options:
16−%% - literate :: turn on literate idris for code environments.
17−%% - numbers :: turn on numbers for code environments.
18−%%
19−%% ----------------------------------------------------------- [ Begin Package ]
20−\ProvidesPackage{idrislang}
21−
22−\RequirePackage{ifthen}
23−\RequirePackage{listings}
24−\RequirePackage{xspace}
25−%% ----------------------------------------------------------------- [ Options ]
26−\newboolean{literate}
27−\setboolean{literate}{false}
28−\newboolean{numbers}
29−\setboolean{numbers}{false}
30−
31−\DeclareOption{literate}{%
32− \setboolean{literate}{true}
33−}
34−
35−\DeclareOption{numbers}{%
36− \setboolean{numbers}{true}
37−}
38−
39−\ProcessOptions\relax
40−
41−%% ---------------------------------------------------------------- [ Commands ]
42−\newcommand{\Idris}{\textsc{Idris}\xspace}
43−\newcommand{\idris}{\textsc{Idris}\xspace}
44−
45−%% --------------------------------------------------- [ Define Idris Listings ]
46−\lstdefinelanguage{idris}{%
47− sensitive,%
48−%% ----------------------------------------------------------- [ Default Style ]
49− basicstyle=\ttfamily,
50− flexiblecolumns=false,
51− commentstyle=\footnotesize\sffamily,
52−%% ---------------------------------------------------------------- [ Keywords ]
53−%% From Idris Parser and idris-mode and vimscript
54− keywords={%
55− abstract, attack, case, compute, do, dsl, else, exact, focus, if,
56− import, in, infix, infixl, infixr, instance, intros, module,
57− mutual, namespace, of, let, parameters, partial, pattern, prefix,
58− private, public, refine, rewrite, solve, syntax, term, then,
59− total, trivial, try, using, where, with
60−},
61−%% ------------------------------------------------------- [ Prelude Functions ]
62−%% Generated using
63−%% find lib/ -name "*.idr" | xargs grep -e "^[a-zA-Z0-9]* :" | awk -F : '{printf $2", "}'
64− morekeywords={%
65− class, data, instance, record, dsl, postulate, default, assert_total,
66− lambda, variable, index_first, index_next
67− % trace, unsafePerformPrimIO, FInt, FChar, FByte, FShort, FLong,
68− % FBits8, FBits16, FBits32, FBits64, FBits8x16, FBits16x8,
69− % FBits32x4, FBits64x2, interpFTy, ForeignTy, mkForeignPrim,
70− % mkLazyForeignPrim, liftPrimIO, fork, unsafePerformIO, listens,
71− % censor, Writer, liftReaderT, asks, Reader, modify, gets, State,
72− % RWS, nGTSm, decideNatLTE, lte, vectInjective1, vectInjective2,
73− % run, myID, send, msgWaiting, recv, recvWithSender, create,
74− % sendToThread, checkMsgs, getMsg, viewB8x16, viewB16x8, viewB32x4,
75− % viewB64x2, pow, exp, log, pi, sin, cos, tan, asin, acos, atan,
76− % atan2, sinh, cosh, tanh, sqrt, floor, ceiling, count, countFrom,
77− % curry, uncurry, uniformB8x16, uniformB16x8, uniformB32x4,
78− % uniformB64x2, putStr, putStrLn, print, getLine, putChar, getChar,
79− % fopen, openFile, closeFile, fread, fwrite, feof, ferror, nullPtr,
80− % nullStr, validFile, while, readFile, userSuppliedName, seq, try,
81− % mkPair, getUName, unApply, mkApp, binderTy, divCeil, nextPow2,
82− % nextBytes, machineTy, bitsUsed, natToBits, getPad, pad8, pad16,
83− % pad32, pad64, shiftLeft, shiftRightLogical, shiftRightArithmetic,
84− % and, or, xor, plus, minus, times, sdiv, udiv, srem, urem, lt, lte,
85− % eq, gte, gt, complement, zeroExtend, intToBits, bitsToInt, bitAt,
86− % getBit, setBit, unsetBit, bitsToStr, findElem, replaceElem,
87− % replaceByElem, mapElem, anyNilAbsurd, anyElim, any, negAnyAll,
88− % notAllHere, notAllThere, all, length, index, weaken, take, toList,
89− % fromList, replicate, foldl, foldr, map, pad, zeroBoundIsEmpty,
90− % empty, insert, delete, contains, fromList, toList, applyKleisli,
91− % applyMor, applyEndo, absZ, negZ, negNat, minusNatZ, plusZ, subZ,
92− % multZ, fromInt, natPlusZPlus, natMultZMult, doubleNegElim,
93− % posInjective, negSInjective, posNotNeg, plusZeroLeftNeutralZ,
94− % plusZeroRightNeutralZ, plusCommutativeZ, modBin, modComp, div,
95− % rem, intToMod, modToStr, branch4, branch5, branch6, branch7,
96− % merge1, merge2, merge3, treeLookup, treeInsert, delType,
97− % treeDelete, treeToList, empty, lookup, insert, delete, fromList,
98− % toList, getWitness, getProof, FalseElim, replace, sym, trans,
99− % lazy, par, malloc, Not, id, the, const, fst, snd, flip, cong,
100− % boolElim, not, intToBool, boolOp, div, mod, strHead, strTail,
101− % strCons, strIndex, reverse, null, getArgs, getEnv, setEnv,
102− % unsetEnv, getEnvironment, exit, usleep, sequence, toHexDigit,
103− % b8ToString, b16ToString, b32ToString, b64ToString, tail, head,
104− % last, init, index, deleteAt, replaceAt, take, drop, fromList,
105− % replicate, zipWith, zip, unzip, concat, elemBy, elem, lookupBy,
106− % lookup, hasAnyBy, hasAny, find, findIndex, elemIndexBy, elemIndex,
107− % nubBy, nub, isPrefixOfBy, isPrefixOf, isSuffixOfBy, isSuffixOf,
108− % catMaybes, diag, range, isLeft, isRight, choose, either, lefts,
109− % rights, partitionEithers, fromEither, maybeToEither, strM, unpack,
110− % pack, span, break, split, ltrim, trim, words, lines, foldr1,
111− % unwords, length, realPart, imagPart, mkPolar, cis, magnitude,
112− % phase, conjugate, isNothing, isJust, maybe, fromMaybe, toMaybe,
113− % justInjective, lowerMaybe, raiseToMaybe, isNil, isCons, head,
114− % tail, last, init, take, drop, takeWhile, dropWhile, list, length,
115− % repeat, replicate, zipWith, zipWith3, zip, zip3, unzip, unzip3,
116− % mapMaybe, toList, reverse, intersperse, intercalate, elemBy, elem,
117− % lookupBy, lookup, hasAnyBy, hasAny, find, findIndex, findIndices,
118− % elemIndexBy, elemIndex, elemIndicesBy, elemIndices, filter, nubBy,
119− % nub, span, break, split, partition, isPrefixOfBy, isPrefixOf,
120− % isSuffixOfBy, isSuffixOf, sorted, mergeBy, merge, sort,
121− % maybeToList, listToMaybe, catMaybes, appendNilRightNeutral,
122− % appendAssociative, lengthAppend, mapPreservesLength,
123− % mapDistributesOverAppend, mapFusion, hasAnyByNilFalse,
124− % hasAnyNilFalse, fromIntegerNat, toIntegerNat, hyper, log2, gcd,
125− % liftA, liftA2, liftA3, guard, when, finToNat, finToInt, weaken,
126− % strengthen, last, natToFin, integerToFin, fromInteger, flatten,
127− % return, isUpper, isLower, isAlpha, isDigit, isAlphaNum, isSpace,
128− % isNL, toUpper, toLower, isHexDigit, isValidHeap, merge, insert,
129− % findMinimum, deleteMinimum, toList, fromList, sort, main, foldl,
130− % concat, concatMap, and, or, any, all, sum, product, Vars,
131− % getAction, setInfo, getInfo, lift, output, queryVars, postVars,
132− % cookieVars, queryVar, getOutput, getHeaders, flushHeaders, flush,
133− % getVars, getContent, getCgiEnv, runCGI, mult
134− },
135−%% ---------------------------------------------------------------- [ Comments ]
136− morecomment=[l]--,%
137− morecomment=[n]{\{-}{-\}}
138−}[keywords,comments,strings]%
139−
140−%% ---------------------------------------- [ Define Idris with Literate Stuff ]
141−\lstdefinelanguage{literateidris}[]{idris}{
142− literate= {+}{{$+$}}1
143− {/}{{$/$}}1
144− {*}{{$*$}}1
145− {=}{{$=$}}1
146− {>}{{$>$}}1
147− {<}{{$<$}}1
148− {\\}{{$\lambda$}}1
149− {\\\\}{{\char`\\\char`\\}}1
150− {->}{{$\rightarrow$}}2
151− {>=}{{$\geq$}}2
152− {<-}{{$\leftarrow$}}2
153− {<=}{{$\leq$}}2
154− {=>}{{$\Rightarrow$}}2
155− {==}{{$\equiv$}}2
156− {\ .}{{$\circ$}}2
157− {\ .\ }{{$\circ$}}2
158− {>>}{{>>}}2
159− {>>=}{{>>=}}2
160− {|}{{$\mid$}}1,
161−}
162−%% -------------------------------------------------- [ Default Listings Style ]
163−
164−\lstdefinestyle{default}{%
165− xleftmargin=\parindent,
166− tabsize=2
167−}
168−\lstdefinestyle{numbers}{%
169− xleftmargin=\parindent,
170− tabsize=2,
171− numbers=left,
172− numbersep=10pt,
173− numberstyle=\footnotesize\sffamily,
174− frame=leftline
175−}
176−
177−%% ------------------------------------------------------ [ A Code Environment ]
178−%% Replicate the existence of literate haskell code environments,
179−%% option to make pretty with numbers.
180−\lstnewenvironment{code}[1][]
181− {\ifthenelse{\boolean{literate}}{%
182− \lstset{language=literateidris}}{%
183− \lstset{language=idris}}
184− \ifthenelse{\boolean{numbers}}{%
185− \lstset{style=numbers, #1}}{%
186− \lstset{style=default, #1}}
187− }
188− {}
189−\endinput
190−%% --------------------------------------------------------------------- [ EOF ]
tutorial/library.ltxdeleted−325
@@ -1,325 +0,0 @@
1−%%%%%%%%%%%%%%% library file for datatypes etc.
2−
3−%%% Identifiers
4−
5−\newcommand{\va}{\VV{a}}
6−\newcommand{\vb}{\VV{b}}
7−\newcommand{\vc}{\VV{c}}
8−\newcommand{\vd}{\VV{d}}
9−\newcommand{\ve}{\VV{e}}
10−\newcommand{\vf}{\VV{f}}
11−\newcommand{\vg}{\VV{g}}
12−\newcommand{\vh}{\VV{h}}
13−\newcommand{\vi}{\VV{i}}
14−\newcommand{\vj}{\VV{j}}
15−\newcommand{\vk}{\VV{k}}
16−\newcommand{\vl}{\VV{l}}
17−\newcommand{\vm}{\VV{m}}
18−\newcommand{\vn}{\VV{n}}
19−\newcommand{\vo}{\VV{o}}
20−\newcommand{\vp}{\VV{p}}
21−\newcommand{\vq}{\VV{q}}
22−\newcommand{\vr}{\VV{r}}
23−\newcommand{\vs}{\VV{s}}
24−\newcommand{\vt}{\VV{t}}
25−\newcommand{\vu}{\VV{u}}
26−\newcommand{\vv}{\VV{v}}
27−\newcommand{\vw}{\VV{w}}
28−\newcommand{\vx}{\VV{x}}
29−\newcommand{\vy}{\VV{y}}
30−\newcommand{\vz}{\VV{z}}
31−\newcommand{\vA}{\VV{A}}
32−\newcommand{\vB}{\VV{B}}
33−\newcommand{\vC}{\VV{C}}
34−\newcommand{\vD}{\VV{D}}
35−\newcommand{\vE}{\VV{E}}
36−\newcommand{\vF}{\VV{F}}
37−\newcommand{\vG}{\VV{G}}
38−\newcommand{\vH}{\VV{H}}
39−\newcommand{\vI}{\VV{I}}
40−\newcommand{\vJ}{\VV{J}}
41−\newcommand{\vK}{\VV{K}}
42−\newcommand{\vL}{\VV{L}}
43−\newcommand{\vM}{\VV{M}}
44−\newcommand{\vN}{\VV{N}}
45−\newcommand{\vO}{\VV{O}}
46−\newcommand{\vP}{\VV{P}}
47−\newcommand{\vQ}{\VV{Q}}
48−\newcommand{\vR}{\VV{R}}
49−\newcommand{\vS}{\VV{S}}
50−\newcommand{\vT}{\VV{T}}
51−\newcommand{\vU}{\VV{U}}
52−\newcommand{\vV}{\VV{V}}
53−\newcommand{\vW}{\VV{W}}
54−\newcommand{\vX}{\VV{X}}
55−\newcommand{\vY}{\VV{Y}}
56−\newcommand{\vZ}{\VV{Z}}
57−\newcommand{\vas}{\VV{as}}
58−\newcommand{\vbs}{\VV{bs}}
59−\newcommand{\vcs}{\VV{cs}}
60−\newcommand{\vds}{\VV{ds}}
61−\newcommand{\ves}{\VV{es}}
62−\newcommand{\vfs}{\VV{fs}}
63−\newcommand{\vgs}{\VV{gs}}
64−\newcommand{\vhs}{\VV{hs}}
65−\newcommand{\vis}{\VV{is}}
66−\newcommand{\vjs}{\VV{js}}
67−\newcommand{\vks}{\VV{ks}}
68−\newcommand{\vls}{\VV{ls}}
69−\newcommand{\vms}{\VV{ms}}
70−\newcommand{\vns}{\VV{ns}}
71−\newcommand{\vos}{\VV{os}}
72−\newcommand{\vps}{\VV{ps}}
73−\newcommand{\vqs}{\VV{qs}}
74−\newcommand{\vrs}{\VV{rs}}
75−%\newcommand{\vss}{\VV{ss}}
76−\newcommand{\vts}{\VV{ts}}
77−\newcommand{\vus}{\VV{us}}
78−\newcommand{\vvs}{\VV{vs}}
79−\newcommand{\vws}{\VV{ws}}
80−\newcommand{\vxs}{\VV{xs}}
81−\newcommand{\vys}{\VV{ys}}
82−\newcommand{\vzs}{\VV{zs}}
83−
84−%%% Telescope Identifiers
85−
86−\newcommand{\ta}{\vec{\VV{a}}}
87−\newcommand{\tb}{\vec{\VV{b}}}
88−\newcommand{\tc}{\vec{\VV{c}}}
89−\newcommand{\td}{\vec{\VV{d}}}
90−\newcommand{\te}{\vec{\VV{e}}}
91−\newcommand{\tf}{\vec{\VV{f}}}
92−\newcommand{\tg}{\vec{\VV{g}}}
93−%\newcommand{\th}{\vec{\VV{h}}}
94−\newcommand{\ti}{\vec{\VV{i}}}
95−\newcommand{\tj}{\vec{\VV{j}}}
96−\newcommand{\tk}{\vec{\VV{k}}}
97−\newcommand{\tl}{\vec{\VV{l}}}
98−\newcommand{\tm}{\vec{\VV{m}}}
99−\newcommand{\tn}{\vec{\VV{n}}}
100−%\newcommand{\to}{\vec{\VV{o}}}
101−\newcommand{\tp}{\vec{\VV{p}}}
102−\newcommand{\tq}{\vec{\VV{q}}}
103−\newcommand{\tr}{\vec{\VV{r}}}
104−\newcommand{\tts}{\vec{\VV{s}}}
105−\newcommand{\ttt}{\vec{\VV{t}}}
106−\newcommand{\tu}{\vec{\VV{u}}}
107−%\newcommand{\tv}{\vec{\VV{v}}}
108−\newcommand{\tw}{\vec{\VV{w}}}
109−\newcommand{\tx}{\vec{\VV{x}}}
110−\newcommand{\ty}{\vec{\VV{y}}}
111−\newcommand{\tz}{\vec{\VV{z}}}
112−\newcommand{\tA}{\vec{\VV{A}}}
113−\newcommand{\tB}{\vec{\VV{B}}}
114−\newcommand{\tC}{\vec{\VV{C}}}
115−\newcommand{\tD}{\vec{\VV{D}}}
116−\newcommand{\tE}{\vec{\VV{E}}}
117−\newcommand{\tF}{\vec{\VV{F}}}
118−\newcommand{\tG}{\vec{\VV{G}}}
119−\newcommand{\tH}{\vec{\VV{H}}}
120−\newcommand{\tI}{\vec{\VV{I}}}
121−\newcommand{\tJ}{\vec{\VV{J}}}
122−\newcommand{\tK}{\vec{\VV{K}}}
123−\newcommand{\tL}{\vec{\VV{L}}}
124−\newcommand{\tM}{\vec{\VV{M}}}
125−\newcommand{\tN}{\vec{\VV{N}}}
126−\newcommand{\tO}{\vec{\VV{O}}}
127−\newcommand{\tP}{\vec{\VV{P}}}
128−\newcommand{\tQ}{\vec{\VV{Q}}}
129−\newcommand{\tR}{\vec{\VV{R}}}
130−\newcommand{\tS}{\vec{\VV{S}}}
131−\newcommand{\tT}{\vec{\VV{T}}}
132−\newcommand{\tU}{\vec{\VV{U}}}
133−\newcommand{\tV}{\vec{\VV{V}}}
134−\newcommand{\tW}{\vec{\VV{W}}}
135−\newcommand{\tX}{\vec{\VV{X}}}
136−\newcommand{\tY}{\vec{\VV{Y}}}
137−\newcommand{\tZ}{\vec{\VV{Z}}}
138−
139−
140−
141−%%% Nat
142−
143−\newcommand{\NatPackage}{
144− \newcommand{\Nat}{\TC{\mathbb{N}}}
145− \newcommand{\Z}{\DC{0}}
146− \newcommand{\suc}{\DC{s}}
147− \newcommand{\NatDecl}{
148− \Data \hg
149− \Axiom{\Nat\Hab\Type} \hg
150− \Where \hg
151− \Axiom{\Z\Hab\Nat} \hg
152− \Rule{\vn\Hab\Nat}
153− {\suc\:\vn\Hab\Nat}
154−}}
155−
156−%%% Bool
157−
158−\newcommand{\BoolPackage}{
159− \newcommand{\Bool}{\TC{Bool}}
160− \newcommand{\true}{\DC{true}}
161− \newcommand{\false}{\DC{false}}
162− \newcommand{\BoolDecl}{
163− \Data \hg
164− \Axiom{\Bool\Hab\Type} \hg
165− \Where \hg
166− \Axiom{\true\Hab\Bool} \hg
167− \Axiom{\false\Hab\Bool}
168−}}
169−
170−%%% So
171−
172−\newcommand{\SoPackage}{
173− \newcommand{\So}{\TC{So}}
174− \newcommand{\oh}{\DC{oh}}
175− \newcommand{\SoDecl}{
176− \Data \hg
177− \Rule{\vb\Hab\Bool}
178− {\So\:\vb\Hab\Type} \hg
179− \Where \hg
180− \Axiom{\oh\Hab\So\:\true}
181−}}
182−
183−%%% Unit
184−
185−\newcommand{\UnitPackage}{
186− \newcommand{\Unit}{\TC{Unit}}
187− \newcommand{\void}{\DC{void}}
188− \newcommand{\UnitDecl}{
189− \Data \hg
190− \Axiom{\Unit\Hab\Type} \hg
191− \Where \hg
192− \Axiom{\void\Hab\Unit}
193−}}
194−
195−%%% Maybe
196−
197−\newcommand{\MaybePackage}{
198− \newcommand{\Maybe}{\TC{Maybe}}
199− \newcommand{\yes}{\DC{yes}}
200− \newcommand{\no}{\DC{no}}
201− \newcommand{\MaybeDecl}{
202− \Data \hg
203− \Rule{\vA\Hab\Type}
204− {\Maybe\:\vA\Hab\Type} \hg
205− \Where \hg
206− \Rule{\va \Hab \vA}
207− {\yes\:\va\Hab\Maybe\:\vA} \hg
208− \Axiom{\no\Hab\Maybe\:\vA}
209−}}
210−
211−%%% Cross
212−
213−\newcommand{\pr}[2]{(#1\DC{,}#2)} %grrrr
214−\newcommand{\CrossPackage}{
215− \newcommand{\Cross}{\times}
216− \newcommand{\CrossDecl}{
217− \Data \hg
218− \Rule{\vA,\vB\Hab\Type}
219− {\vA\Cross\vB\Hab\Type} \hg
220− \Where \hg
221− \Rule{\va \Hab \vA \hg \vb\Hab\vB}
222− {\pr{\va}{\vb}\Hab\vA\Cross\vB}
223−}}
224−
225−%%% Fin
226−
227−\newcommand{\FinPackage}{
228− \newcommand{\Fin}{\TC{Fin}}
229− \newcommand{\fz}{\DC{f0}}
230− \newcommand{\fs}{\DC{fs}}
231− \newcommand{\FinDecl}{
232− \AR{
233− \Data \hg
234− \Rule{\vn\Hab\Nat}
235− {\Fin\:\vn\Hab\Type} \hg \\
236− \Where \hg
237− \begin{array}[t]{c}
238− \Axiom{\fz\Hab\Fin\:(\suc\:\vn)} \hg
239− \Rule{\vi\Hab\Fin\:\vn}
240− {\fs\:\vi\Hab\Fin\:(\suc\:\vn)}
241− \end{array}
242− }
243−}}
244−
245−%%% Vect
246−
247−\newcommand{\VectPackage}{
248− \newcommand{\Vect}{\TC{Vect}}
249− \newcommand{\vnil}{\varepsilon}
250− \newcommand{\vcons}{\,\dcolon\,}
251− \newcommand{\vsnoc}{\,\dcolon\,}
252− \newcommand{\VectConsDecl}{
253− \Data \hg
254− \Rule{\vA \Hab \Type \hg \vn\Hab\Nat}
255− {\Vect\:\vA\:\vn\Hab\Type} \hg
256− \Where \hg \begin{array}[t]{c}
257− \Axiom{\vnil \Hab \Vect\:\vA\:\Z} \\
258− \Rule{\vx\Hab\vA \hg \vxs\Hab \Vect\:\vA\:\vn }
259− {\vx\vcons\vxs\Hab\Vect\:\vA\:(\suc\vn)}
260− \end{array}
261−}
262− \newcommand{\VectSnocDecl}{
263− \Data \hg
264− \Rule{\vA \Hab \Type \hg \vn\Hab\Nat}
265− {\Vect\:\vA\:\vn\Hab\Type} \hg
266− \Where \hg \begin{array}[t]{c}
267− \Axiom{\vnil \Hab \Vect\:\vA\:\Z} \\
268− \Rule{\vxs\Hab \Vect\:\vA\:\vn \hg \vx\Hab\vA}
269− {\vxs\vsnoc\vx\Hab\Vect\:\vA\:(\suc\vn)}
270− \end{array}
271−}
272−}
273−
274−%%% Compare
275−
276−%Data Compare : (x:nat)(y:nat)Type
277−% = lt : (x:nat)(y:nat)(Compare x (plus (S y) x))
278−% | eq : (x:nat)(Compare x x)
279−% | gt : (x:nat)(y:nat)(Compare (plus (S x) y) y);
280−
281−
282−\newcommand{\ComparePackage}{
283− \newcommand{\Compare}{\TC{Compare}}
284− \newcommand{\ltComp}{\DC{lt}}
285− \newcommand{\eqComp}{\DC{eq}}
286− \newcommand{\gtComp}{\DC{gt}}
287− \newcommand{\CompareDecl}{
288− \Data \hg
289− \Rule{\vm\Hab\Nat\hg\vn\Hab\Nat}
290− {\Compare\:\vm\:\vn\Hab\Type} \\
291− \Where \hg\begin{array}[t]{c}
292− \Rule{\vx\Hab\Nat\hg\vy\Hab\Nat}
293− {\ltComp_{\vx}\:\vy\Hab\Compare\:\vx\:(\FN{plus}\:\vx\:(\suc\:\vy))} \\
294− \Rule{\vx\Hab\Nat}
295− {\eqComp_{\vx}\Hab\Compare\:\vx\:\vx}\\
296− \Rule{\vx\Hab\Nat\hg\vy\Hab\Nat}
297− {\gtComp_{\vy}\:\vx\Hab\Compare\:(\FN{plus}\:\vy\:(\suc\:\vx))\:\vy} \\
298− \end{array}
299− }
300−
301−%Data CompareM : Type
302−% = ltM : (ydiff:nat)CompareM
303−% | eqM : CompareM
304−% | gtM : (xdiff:nat)CompareM;
305−
306− \newcommand{\CompareM}{\TC{Compare^-}}
307− \newcommand{\ltCompM}{\DC{lt^-}}
308− \newcommand{\eqCompM}{\DC{eq^-}}
309− \newcommand{\gtCompM}{\DC{gt^-}}
310− \newcommand{\CompareMDecl}{
311−
312− \Data \hg
313− \Axiom{\CompareM\Hab\Type} \\
314− \Where \hg\begin{array}[t]{c}
315− \Rule{\vy\Hab\Nat}
316− {\ltCompM\:\vy\Hab\CompareM} \\
317− \Axiom{\eqCompM\Hab\CompareM}\\
318− \Rule{\vx\Hab\Nat}
319− {\gtCompM\:\vx\Hab\CompareM} \\
320− \end{array}
321− }
322− \newcommand{\CompareRec}{\FN{CompareRec}}
323− \newcommand{\CompareRecM}{\FN{CompareRec^-}}
324−
325−}
tutorial/literature.bibdeleted−3856
@@ -1,3856 +0,0 @@
1−@inproceedings{res-dsl-padl12,
2− title = {Resource-safe Systems Programming with Embedded Domain Specific Languages},
3− year = {2012},
4− booktitle = {Practical Applications of Declarative Languages 2012},
5− author = {Edwin Brady and Kevin Hammond},
6− series = {LNCS},
7− publisher = {Springer},
8− note = {To appear}
9−}
10−
11−@article{lambdapi,
12− author = {Andres L\"{o}h and Conor McBride and Wouter Swierstra},
13− title = {A tutorial implementation of a dependently typed lambda calculus},
14− year = 2010,
15− journal = {Fundamenta Informaticae},
16− volume = 102,
17− number = 2
18−}
19−
20−@article{idioms,
21− author = {McBride, Conor and Paterson, Ross},
22− title = {Applicative programming with effects},
23− journal = {J. Funct. Program.},
24− volume = {18},
25− issue = {1},
26− month = {January},
27− year = {2008},
28− issn = {0956-7968},
29− pages = {1--13},
30− numpages = {13},
31− url = {http://portal.acm.org/citation.cfm?id=1348940.1348941},
32− doi = {10.1017/S0956796807006326},
33− acmid = {1348941},
34− publisher = {Cambridge University Press},
35− address = {New York, NY, USA},
36−}
37−
38−@inproceedings{lava,
39− author = {Bjesse, Per and Claessen, Koen and Sheeran, Mary and Singh, Satnam},
40− title = {Lava: hardware design in {Haskell}},
41− booktitle = {Proceedings of the third ACM SIGPLAN international conference on Functional programming},
42− series = {ICFP '98},
43− year = {1998},
44− isbn = {1-58113-024-4},
45− location = {Baltimore, Maryland, United States},
46− pages = {174--184},
47− numpages = {11},
48− url = {http://doi.acm.org/10.1145/289423.289440},
49− doi = {http://doi.acm.org/10.1145/289423.289440},
50− acmid = {289440},
51− publisher = {ACM},
52− address = {New York, NY, USA},
53−}
54−
55−@inproceedings{plpv11,
56− author = {Edwin Brady},
57− title = {Idris --- Systems programming meets full dependent types},
58− booktitle = {Programming Languages meets Program Verification {(PLPV 2011)}},
59− year = {2011},
60− pages = {43--54},
61− ee = {http://doi.acm.org/10.1145/1929529.1929536},
62− bibsource = {DBLP, http://dblp.uni-trier.de}
63−}
64−
65−@inproceedings{epic-tfp,
66− author = {Edwin Brady},
67− title = {Epic --- a library for generating compilers},
68− year = 2011,
69− booktitle = {{Trends in Functional Programming} ({TFP} '11)},
70− note = {To appear}
71−}
72−
73−@inproceedings{ynot08,
74− author = {Nanevski,, Aleksandar and Morrisett,, Greg and
75− Shinnar,, Avraham and Govereau,, Paul and Birkedal,,
76− Lars},
77− title = {Ynot: reasoning with the awkward squad},
78− booktitle = {{ICFP} '08: Proceeding of the 13th {ACM SIGPLAN}
79− international conference on Functional programming},
80− year = {2008},
81− isbn = {978-1-59593-919-7},
82− pages = {229--240},
83− location = {Victoria, BC, Canada},
84− doi = {http://doi.acm.org/10.1145/1411204.1411237},
85− publisher = {ACM},
86− address = {New York, NY, USA},
87−}
88−
89−@article{cbconc-fi,
90− author = {Edwin Brady and Kevin Hammond},
91− title = {Correct-by-Construction Concurrency: Using Dependent Types to Verify Implementations of Effectful Resource Usage Protocols},
92− year = 2010,
93− journal = {Fundamenta Informaticae},
94− volume = 102,
95− number = 2,
96− pages = {145--176}
97−}
98−
99−@inproceedings{devil-osdi00,
100− author = {Fabrice M{\'e}rillon and
101− Laurent R{\'e}veill{\`e}re and
102− Charles Consel and
103− Renaud Marlet and
104− Gilles Muller},
105− title = {Devil: An IDL for Hardware Programming},
106− booktitle = {4th USENIX Symposium on Operating Systems Design and Implementation (OSDI 2000)},
107− year = {2000}
108−}
109−
110−
111−@INPROCEEDINGS{device-osdi08,
112− author = {Dan Williams and Patrick Reynolds and Kevin Walsh and Emin Gün Sirer and Fred B. Schneider},
113− title = {Device driver safety through a reference validation mechanism},
114− booktitle = {8th USENIX Symposium on Operating Systems Design and Implementation (OSDI 2008)},
115− year = {2008}
116−}
117−
118−@inproceedings{sozeau-equations,
119− author = {Matthieu Sozeau},
120− title = {Equations: A Dependent Pattern-Matching Compiler},
121− booktitle = {First International Conference on Interactive Theorem Proving (ITP 2010)},
122− year = {2010},
123− pages = {419--434},
124− ee = {http://dx.doi.org/10.1007/978-3-642-14052-5_29},
125− crossref = {DBLP:conf/itp/2010},
126− bibsource = {DBLP, http://dblp.uni-trier.de}
127−}
128−
129−
130−@inproceedings{packet-type,
131− author = "Peter J. McCann and Satish Chandra",
132− title = "Packet Types: Abstract Specification of Network Protocol Messages",
133− year = 2000,
134− booktitle = "SIGCOMM '00",
135− publisher = {{ACM}}
136−}
137−
138−@inproceedings{qs-types,
139− author = {Eelis {van der Weegen} and James McKinna},
140−
141− title={A Machine-checked Proof of the Average-case Complexity of Quicksort in Coq},
142− year={2009},
143− pages={256--271},
144− series = {Lecture Notes in Computer Science},
145− publisher = {Springer}
146−
147−}
148−
149−@inproceedings{totalparser,
150− author = {Nils Anders Danielsson},
151− title = {Total Parser Combinators},
152− booktitle = {{ICFP} '10: Proceedings of the 15th {ACM} {SIGPLAN} International Conference on Functional Programming},
153− year = {2010},
154− isbn = {978-1-60558-794-3},
155− pages = {285--296},
156− location = {Baltimore, Maryland, USA},
157− doi = {http://doi.{ACM}.org/10.1145/1863543.1863587},
158− publisher = {{ACM}},
159− address = {New York, NY, USA},
160− }
161−
162−@misc{rfc791,
163− author="J. Postel",
164− title="{Internet Protocol}",
165− series="Request for Comments",
166− number="791",
167− howpublished="RFC 791 (Standard)",
168− publisher="IETF",
169− organization="Internet Engineering Task Force",
170− year=1981,
171− month=sep,
172− note="Updated by RFC 1349",
173− url="http://www.ietf.org/rfc/rfc791.txt",
174−}
175−
176−
177−@misc{rfc792,
178− author="J. Postel",
179− title="{Internet Control Message Protocol}",
180− series="Request for Comments",
181− number="792",
182− howpublished="RFC 792 (Standard)",
183− publisher="IETF",
184− organization="Internet Engineering Task Force",
185− year=1981,
186− month=sep,
187− note="Updated by RFCs 950, 4884",
188− url="http://www.ietf.org/rfc/rfc792.txt",
189−}
190−
191−@INPROCEEDINGS{Dybjer-indrec,
192− author = {Peter Dybjer and Anton Setzer},
193− title = {A Finite Axiomatization of Inductive-Recursive Definitions},
194− booktitle = {Tyed Lambda Calculi and Applications},
195− volume = {1581},
196− series = {Lecture Notes in Computer Science},
197− year = {1998},
198− pages = {129--146},
199− publisher = {Springer}
200−}
201−
202−@book{stevenstcpip,
203− author = {W. Richard Stevens},
204− title = {{TCP/IP} Illustrated Volume 1: The Protocols},
205− year = 1994,
206− publisher = {Addison Wesley},
207− isbn = {0-201-63346-9}
208−}
209−
210−@inproceedings{coqtypeclasses,
211− author = {Sozeau, Matthieu and Oury, Nicolas},
212− title = {First-Class Type Classes},
213− booktitle = {TPHOLs '08: Proceedings of the 21st International Conference on Theorem Proving in Higher Order Logics},
214− year = {2008},
215− isbn = {978-3-540-71065-3},
216− pages = {278--293},
217− location = {Montreal, P.Q., Canada},
218− doi = {http://dx.doi.org/10.1007/978-3-540-71067-7_23},
219− publisher = {Springer-Verlag},
220− address = {Berlin, Heidelberg},
221− }
222−
223−
224−@inproceedings{kipling,
225− author = {McBride, Conor},
226− title = {Outrageous but meaningful coincidences: dependent type-safe syntax and evaluation},
227− booktitle = {WGP '10: Proceedings of the 6th {ACM} {SIGPLAN} workshop on Generic programming},
228− year = {2010},
229− isbn = {978-1-4503-0251-7},
230− pages = {1--12},
231− location = {Baltimore, Maryland, USA},
232− doi = {http://doi.{ACM}.org/10.1145/1863495.1863497},
233− publisher = {{ACM}},
234− address = {New York, NY, USA},
235− }
236−
237−@inproceedings{padsml,
238− author = {Yitzhak Mandelbaum and
239− Kathleen Fisher and
240− David Walker and
241− Mary F. Fern{\'a}ndez and
242− Artem Gleyzer},
243− title = {{PADS/ML}: a functional data description language},
244− booktitle = {POPL '07: Proceedings of the 34th {ACM} {SIGPLAN}-SIGACT Symposium on
245− Principles of Programming Languages, POPL 2007, Nice, France,
246− January 17-19, 2007},
247− year = {2007},
248− pages = {77-83},
249− ee = {http://doi.{ACM}.org/10.1145/1190216.1190231},
250− crossref = {DBLP:conf/popl/2007},
251− bibsource = {DBLP, http://dblp.uni-trier.de}
252−}
253−
254−@proceedings{DBLP:conf/popl/2007,
255− editor = {Martin Hofmann and
256− Matthias Felleisen},
257− title = {Proceedings of the 34th {ACM} {SIGPLAN}-SIGACT Symposium on
258− Principles of Programming Languages, POPL 2007, Nice, France,
259− January 17-19, 2007},
260− booktitle = {POPL},
261− publisher = {{ACM}},
262− year = {2007},
263− isbn = {1-59593-575-4},
264− bibsource = {DBLP, http://dblp.uni-trier.de}
265−}
266−
267−@inproceedings{melange,
268− author = {Madhavapeddy, Anil and Ho, Alex and Deegan, Tim and Scott, David and Sohan, Ripduman},
269− title = {Melange: creating a "functional" internet},
270− booktitle = {EuroSys '07: Proceedings of the 2nd {ACM} SIGOPS/EuroSys European Conference on Computer Systems 2007},
271− year = {2007},
272− isbn = {978-1-59593-636-3},
273− location = {Lisbon, Portugal},
274− doi = {http://doi.{ACM}.org/10.1145/1272996.1273009},
275− publisher = {{ACM}},
276− address = {New York, NY, USA},
277− }
278−
279−
280−
281−@article{next700data,
282− author = {Fisher, Kathleen and Mandelbaum, Yitzhak and Walker, David},
283− title = {The next 700 data description languages},
284− journal = {{SIGPLAN} Not.},
285− volume = {41},
286− number = {1},
287− year = {2006},
288− issn = {0362-1340},
289− pages = {2--15},
290− doi = {http://doi.{ACM}.org/10.1145/1111320.1111039},
291− publisher = {{ACM}},
292− address = {New York, NY, USA},
293− }
294−
295−
296−@INPROCEEDINGS{xi-ats,
297− author = {Hongwei Xi},
298− title = {{Applied Type System} (extended abstract)},
299− booktitle = {Types for Proofs and Programs 2003},
300− editor = {Stefano Berardi and Mario Coppo and Ferruccio Damiani},
301− publisher = {Springer},
302− series = {Lecture Notes in Computer Science},
303− volume = {3085},
304− year = {2004},
305− pages = {394--408}
306−}
307−
308−@inproceedings{powerpi,
309− author = {Nicolas Oury and
310− Wouter Swierstra},
311− title = {The power of {Pi}},
312− booktitle = {{ICFP} '08: Proceedings of the 13th {ACM} {SIGPLAN} International Conference
313− on Functional Programming, {ICFP} 2008, Victoria, BC, Canada,
314− September 20-28, 2008},
315− year = {2008},
316− pages = {39--50},
317− ee = {http://doi.{ACM}.org/10.1145/1411204.1411213},
318− crossref = {DBLP:conf/{ICFP}/2008},
319− bibsource = {DBLP, http://dblp.uni-trier.de}
320−}
321−
322−@proceedings{DBLP:conf/{ICFP}/2008,
323− editor = {James Hook and
324− Peter Thiemann},
325− title = {Proceeding of the 13th {ACM} {SIGPLAN} international conference
326− on Functional programming, {ICFP} 2008, Victoria, BC, Canada,
327− September 20-28, 2008},
328− booktitle = {{ICFP}},
329− publisher = {{ACM}},
330− year = {2008},
331− isbn = {978-1-59593-919-7},
332− bibsource = {DBLP, http://dblp.uni-trier.de}
333−}
334−
335−
336−@inproceedings{security-types,
337− author = {Morgenstern, Jamie and Licata, Daniel R.},
338− title = {Security-typed programming within dependently typed programming},
339− booktitle = {{ICFP} '10: Proceedings of the 15th {ACM} {SIGPLAN} International Conference on Functional Programming},
340− year = {2010},
341− isbn = {978-1-60558-794-3},
342− pages = {169--180},
343− location = {Baltimore, Maryland, USA},
344− doi = {http://doi.{ACM}.org/10.1145/1863543.1863569},
345− publisher = {{ACM}},
346− address = {New York, NY, USA},
347− }
348−
349−@inproceedings{levitation,
350− author = {Chapman, James and Dagand, Pierre-\'{E}variste and McBride, Conor and Morris, Peter},
351− title = {The gentle art of levitation},
352− booktitle = {{ICFP} '10: Proceedings of the 15th {ACM} {SIGPLAN} International Conference on Functional Programming},
353− year = {2010},
354− isbn = {978-1-60558-794-3},
355− pages = {3--14},
356− location = {Baltimore, Maryland, USA},
357− doi = {http://doi.{ACM}.org/10.1145/1863543.1863547},
358− publisher = {{ACM}},
359− address = {New York, NY, USA},
360− }
361−
362−
363−
364−@INPROCEEDINGS{awkward,
365− author = {Simon {Peyton Jones}},
366− title = {Tackling the awkward squad: monadic input/output, concurrency, exceptions, and foreign-language calls in {Haskell}},
367− booktitle = {Engineering theories of software construction},
368− year = {2001},
369− pages = {47--96}
370−}
371−
372−@inproceedings{scrap-engine,
373− author = {Brady, Edwin and Hammond, Kevin},
374− title = {Scrapping your inefficient engine: using partial evaluation to improve domain-specific language implementation},
375− booktitle = {{ICFP} '10: Proceedings of the 15th {ACM} {SIGPLAN} International Conference on Functional Programming},
376− year = {2010},
377− isbn = {978-1-60558-794-3},
378− pages = {297--308},
379− location = {Baltimore, Maryland, USA},
380− doi = {http://doi.{ACM}.org/10.1145/1863543.1863587},
381− publisher = {{ACM}},
382− address = {New York, NY, USA},
383− }
384−
385−@article{urweb,
386− author = {Chlipala, Adam},
387− title = {Ur: statically-typed metaprogramming with type-level record computation},
388− journal = {{SIGPLAN} Not.},
389− volume = {45},
390− number = {6},
391− year = {2010},
392− issn = {0362-1340},
393− pages = {122--133},
394− doi = {http://doi.{ACM}.org/10.1145/1809028.1806612},
395− publisher = {{ACM}},
396− address = {New York, NY, USA},
397− }
398−
399−
400−
401−@phdthesis{norell-thesis,
402− author = {Ulf Norell},
403− title = {Towards a practical programming language based on dependent type
404− theory},
405− school = {Chalmers University of Technology},
406− year = 2007,
407− month = {September},
408−}
409−
410−@inproceedings{open-type,
411− author = {Schrijvers, Tom and Peyton Jones, Simon and Chakravarty, Manuel and Sulzmann, Martin},
412− title = {Type checking with open type functions},
413− booktitle = {International Conf. on Functional Programming ({ICFP} 2008)},
414− year = {2008},
415− pages = {51--62},
416− doi = {http://doi.{ACM}.org/10.1145/1411203.1411215},
417− publisher = {{ACM}},
418− address = {New York, NY, USA},
419− }
420−
421−@inproceedings{ngna-dsl,
422− title = {Domain Specific Languages ({DSL}s) for Network Protocols},
423− author = {Saleem Bhatti and Edwin Brady and Kevin Hammond and James McKinna},
424− year = {2009},
425− booktitle = {International Workshop on Next Generation Network Architecture ({NGNA} 2009)}
426−}
427−
428−@phdthesis{gill-thesis,
429− title = {Cheap deforestation for non-strict functional languages},
430− author = {A Gill},
431− institution = {University of Glasgow},
432− month = {January},
433− year = 1996
434−}
435−
436−@misc{llvm-haskell,
437− title = {Low Level Virtual Machine for {Glasgow Haskell Compiler}},
438− author = {David Terei},
439− year = 2009,
440− howpublished = {Bachelor's Thesis, Computer Science and Engineering Dept., The University of New South Wales, Sydney, Australia}
441−}
442−
443−@mastersthesis{llvm,
444− title = {{LLVM}: An Infrastructure for Multi-Stage Optimization},
445− author = {Chris Lattner},
446− year = 2002,
447− month = {December},
448− institution = {Computer Science Dept., University of Illinois at Urbana-Champaign}
449−}
450−
451−@inproceedings{gpu-arrays,
452− title = {GPU Kernels as Data-Parallel Array Computations in Haskell},
453− author = {Sean Lee and Manuel M. T. Chakravarty and Vinod Grover and Gabriele Keller.},
454− year = 2009,
455− booktitle = {Workshop on Exploiting Parallelism using GPUs and other Hardware-Assisted Methods (EPAHM 2009)}
456−}
457−
458−@misc{cryptol,
459− author = {Galois, Inc.},
460− title = {Cryptol},
461− year = {2009},
462− howpublished = {\url{http://cryptol.net/}}
463−}
464−
465−@inproceedings{paradise-dsl,
466− author = {Lennart Augustsson and Howard Mansell and Ganesh Sittampalam},
467− title = {{Paradise: a two-stage DSL embedded in Haskell}},
468− booktitle = {International Conf. on Functional Programming ({ICFP} 2008)},
469− year = {2008},
470− publisher = {{ACM}},
471− pages = {225--228}
472− }
473−
474−@misc{dsl-bib,
475− author = {Arie {van Deursen} and Paul Klint and Joost Visser},
476− title = {Domain-Specific Languages --- an annotated bibliography},
477− year = 2000,
478− howpublished = {\url{http://homepages.cwi.nl/~arie/papers/dslbib/}}
479−}
480−
481−@inproceedings{imperative-pe,
482− author = {Debois, S{\o}ren},
483− title = {Imperative program optimization by partial evaluation},
484− booktitle = {PEPM '04: Proceedings of the 2004 {ACM} {SIGPLAN} symposium on Partial evaluation and semantics-based program manipulation},
485− year = {2004},
486− isbn = {1-58113-835-0},
487− pages = {113--122},
488− location = {Verona, Italy},
489− doi = {http://doi.{ACM}.org/10.1145/1014007.1014019},
490− publisher = {{ACM}},
491− address = {New York, NY, USA},
492− }
493−
494−
495−@inproceedings{offline-pe-termination,
496− author = {Andersen, Peter Holst and Holst, Carsten Kehler},
497− title = {Termination Analysis for Offline Partial Evaluation of a Higher Order Functional Language},
498− booktitle = {Proc. SAS '96: Intl. Symp. on Static Analysis},
499− year = {1996},
500− isbn = {3-540-61739-6},
501− pages = {67--82},
502− publisher = {Springer},
503− notaddress = {London, UK},
504− }
505−
506−
507−@inproceedings{stage-duplication,
508− author = {Swadi, Kedar and Taha, Walid and Kiselyov, Oleg and Pasalic, Emir},
509− title = {A monadic approach for avoiding code duplication when staging memoized functions},
510− notbooktitle = {PEPM '06: Proceedings of the 2006 {ACM} {SIGPLAN} symposium on Partial evaluation and semantics-based program manipulation},
511− booktitle = {Proc. PEPM '06:{ACM} Symp. on Partial Evaluation and Semantics-based Program Manipulation},
512− year = {2006},
513− isbn = {1-59593-196-1},
514− pages = {160--169},
515− location = {Charleston, South Carolina},
516− doi = {http://doi.{ACM}.org/10.1145/1111542.1111570},
517− notpublisher = {{ACM}},
518− notaddress = {New York, NY, USA},
519− }
520−
521−
522−@inproceedings{concoqtion,
523− author = {Fogarty, Seth and Pasalic, Emir and Siek, Jeremy and Taha, Walid},
524− title = {Concoqtion: indexed types now!},
525− booktitle = {PEPM '07: Proceedings of the 2007 {ACM} {SIGPLAN} symposium on Partial evaluation and semantics-based program manipulation},
526− year = {2007},
527− isbn = {978-1-59593-620-2},
528− pages = {112--121},
529− location = {Nice, France},
530− doi = {http://doi.{ACM}.org/10.1145/1244381.1244400},
531− publisher = {{ACM}},
532− address = {New York, NY, USA},
533− }
534−
535−@inproceedings{metahaskell,
536− author = "Tim Sheard and Simon {Peyton Jones}",
537− title = "Template metaprogramming for {Haskell}",
538− booktitle = "{ACM} Haskell Workshop",
539− year = 2002,
540− month = oct,
541− pages = "1-16",
542− noteditor = "Manuel M. T. Chakravarty",
543− notpublisher = "{ACM} Press"
544−}
545−
546−@misc{shark-profiler,
547− title = {Optimizing your application with {Shark 4}},
548− year = 2009,
549− howpublished = {\url{http://developer.apple.com/tools/sharkoptimize.html}}
550−}
551−
552−@misc{shootout,
553− title = {The Computer Language Benchmark Game},
554− year = {2009},
555− howpublished = {\url{http://shootout.alioth.debian.org/}}
556−}
557−
558−@article{futamura,
559− author = {Yoshihiko Futamura},
560− year = 1971,
561− title = "Partial Evaluation of Computation Process --– An Approach to a Compiler-Compiler",
562− journal = {Systems, Comps., Controls},
563− volume = 2,
564− number = 5,
565− pages = {45-–50}
566−}
567−
568−@book{pebook,
569− title = {Partial Evaluation and Automatic Program Generation},
570− author = {N.D. Jones and C.K. Gomard and P. Sestoft},
571− year = 1993,
572− publisher = {Prentice Hall International}
573−}
574−
575−@inproceedings{pantheon,
576− author = {Sean Seefried and Manuel Chakravarty and Gabriele Keller},
577− title = {Optimising Embedded {DSLs} using {Template Haskell}},
578− year = {2004},
579− booktitle = {{Proc. GPCE~'04: Conf. Generative Prog. and Component Eng.}},
580− publisher = {Springer},
581− series = {LNCS}
582−}
583−
584−@article{pan,
585− author = {Elliott, Conal and Finne, Sigbj\orn and De Moor, Oege},
586− title = {Compiling embedded languages},
587− journal = {J. Funct. Program.},
588− volume = {13},
589− number = {3},
590− year = {2003},
591− issn = {0956-7968},
592− pages = {455--481},
593− doi = {http://dx.doi.org/10.1017/S0956796802004574},
594− publisher = {Cambridge University Press},
595− address = {New York, NY, USA},
596− }
597−
598−
599−@inproceedings{russell,
600− author = {Sozeau, Matthieu},
601− title = {Program-ing finger trees in Coq},
602− booktitle = {{ICFP} '07: Proceedings of the 12th {ACM} {SIGPLAN} international conference on Functional programming},
603− year = {2007},
604− isbn = {978-1-59593-815-2},
605− pages = {13--24},
606− location = {Freiburg, Germany},
607− doi = {http://doi.{ACM}.org/10.1145/1291151.1291156},
608− publisher = {{ACM}},
609− address = {New York, NY, USA},
610− }
611−
612−@inproceedings{turner-total,
613− author = {D. A. Turner},
614− title = {Elementary Strong Functional Programming},
615− year = 1995,
616− booktitle = "First International Symposium on Functional Programming Languages in Education",
617− publisher = {Springer},
618− series = {LNCS},
619− volume = {1022},
620− pages = {1--13}
621−}
622−
623−@incollection{free-theorems,
624− author = "P. Wadler",
625− title = "Theorems for Free!",
626− booktitle = "{Proc. 4th Int.\ Conf.\ on Funct.\ Prog.\ Languages and Computer Arch., {FPCA}'89, London, {UK}, 11--13 Sept 1989}",
627− publisher = "{ACM} Press",
628− address = "New York",
629− pages = "347--359",
630− year = "1989",
631− url = "citeseer.ist.psu.edu/wadler89theorems.html"
632−}
633−
634−@inproceedings{TrulyConcurrent,
635− author = {Naiyong Jin and Jifeng He},
636− title = {Towards A Truly Concurrent Model for Processes Sharing Resources},
637− booktitle = {Proc. 3rd {IEEE} International Conf. on Soft. Eng. and Formal Methods},
638− year = {2005},
639− isbn = {0-7695-2435-4},
640− pages = {231--239},
641− doi = {http://dx.doi.org/10.1109/SEFM.2005.50},
642− publisher = {{IEEE} Computer Society},
643− address = {Washington, DC, USA},
644− }
645−
646−@misc{GPCE2006,
647− note = {Omitted to preserve anonymity, contact PC chair for details}
648−}
649−
650−@misc{IFL2006,
651− note = {Omitted to preserve anonymity, contact PC chair for details}
652−}
653−
654−@misc{ivor-anon,
655− note = {Omitted to preserve anonymity, contact PC chair for details}
656−}
657−
658−@inproceedings{HaskellIO,
659− author = {Simon L. {Peyton Jones} and Philip Wadler},
660− title = {Imperative functional programming},
661− booktitle = {Proc. 20th {ACM} Symposium on Principles of programming languages},
662− year = {1993},
663− isbn = {0-89791-560-7},
664− pages = {71--84},
665− location = {Charleston, South Carolina, United States},
666− doi = {http://doi.{ACM}.org/10.1145/158511.158524},
667− publisher = {{ACM}},
668− address = {New York, NY, USA},
669− }
670−
671−@article{CorrectnessConstruction,
672−author = "P. Amey",
673−title = "{Correctness by Construction: Better can also be Cheaper}",
674−journal = "{CrossTalk: the Journal of Defense Software Engineering}",
675−month = mar,
676−year = 2002,
677−pages = "24--28"
678−}
679−
680−
681−
682−@INPROCEEDINGS{hj:popl03,
683− AUTHOR = {M. Hofmann and S. Jost},
684− TITLE = {Static Prediction of Heap Space Usage for First-Order Function
685−al Programs},
686−booktitle = "Proc. {POPL 2003 --- 2003 {ACM} Symp. on Principles of Programming La
687−nguages}",
688− KEY = {HJ_POPL03},
689− PAGES = {185--197},
690− YEAR = {2003},
691− ORGANIZATION = {{ACM}}
692−}
693−
694−
695−@article{kobayashi-lock,
696− author = {Naoki Kobayashi},
697− title = {A type system for lock-free processes},
698− journal = {Inf. Comput.},
699− volume = {177},
700− number = {2},
701− year = {2002},
702− issn = {0890-5401},
703− pages = {122--159},
704− doi = {http://dx.doi.org/10.1016/S0890-5401(02)93171-8},
705− publisher = {Academic Press, Inc.},
706− address = {Duluth, MN, USA},
707− }
708−
709−@techreport{linear-alias,
710− title = {Linear types for aliased resources},
711− author = {Chris Hawblitzel},
712− year = {2005},
713− institution = {Microsoft Research},
714− number = {MSR-TR-2005-141}
715−}
716−
717−@article{kobayashi-esop,
718− title = {Type-Based Analysis of Deadlock fora Concurrent Calculus with Interrupts},
719− author = {Kohei Suenaga and Naoki Kobayashi},
720− year = {2007},
721− booktitle = {ESOP}
722−}
723−
724−@inproceedings{res-c,
725− title = {A Path Sensitive Type System for Resource Usage Verification of C Like Languages},
726− author = {Hyun-Goo Kang and Youil Kim and Taisook Han and Hwansoo Han},
727− year = 2005,
728− publisher = {Springer-Verlag},
729− booktitle = {Programming Languages and Systems},
730− pages = {264--280},
731− series = {LNCS},
732− volume = {3780}
733−}
734−
735−@miscs{lsr,
736− title = {Lightweight static resources: Sexy types for embedded and systems programming},
737− author = {Oleg Kiselyov and Chung-Chieh Shan},
738− year = 2007,
739− note = {Draft}
740−}
741−
742−@inproceedings{scoped-res,
743− title = {Resource Usage Analysis Via Scoped Methods},
744− author = {Gang Tan and Xinming Ou and David Walker},
745− booktitle = {Foundations of Object-Oriented Languages},
746− year = {2003}
747−}
748−
749−@article{igarashi-res,
750− author = {Igarashi, Atsushi and Kobayashi, Naoki},
751− title = {Resource usage analysis},
752− journal = {ACM Trans. Program. Lang. Syst.},
753− volume = {27},
754− issue = {2},
755− month = {March},
756− year = {2005},
757− issn = {0164-0925},
758− pages = {264--313},
759− numpages = {50},
760− url = {http://doi.acm.org/10.1145/1057387.1057390},
761− doi = {http://doi.acm.org/10.1145/1057387.1057390},
762− acmid = {1057390},
763− publisher = {ACM},
764− address = {New York, NY, USA},
765− keywords = {Resource usage, type inference},
766−}
767−
768−@phdthesis{monitoring,
769− title = {Policy Enforcement via Program Monitoring},
770− author = {Jarred Adam Ligatti},
771− year = 2006,
772− month = {May}
773−}
774−
775−@inproceedings{sec-policy,
776− title = {A Type System for Expressive Security Policies},
777− author = {David Walker},
778− booktitle = {Twenty-Seventh {ACM} {SIGPLAN} Symposium on Principles of Programming Languages},
779− pages = {254--267},
780− year = 2000}
781−
782−@inproceedings{res-dfa,
783− author = {K. Marriott and P.J. Stuckey and M. Sulzmann},
784− title = {Resource Usage Verification},
785− year = 2003,
786− booktitle = {In Proc. of First Asian Symposium, APLAS 2003},
787− pages = {212--229},
788− publisher = {Springer-Verlag}
789−}
790−
791−@incollection{ hancock-interactive,
792− author = "Peter Hancock and Anton Setzer",
793− title = "Interactive Programs in Dependent Type Theory",
794− booktitle = "Proc.\ of 14th Ann.\ Conf.\ of {EACSL}, {CSL}'00, Fischbau, Germany, 21--26 Aug 2000",
795− volume = "1862",
796− publisher = "Springer-Verlag",
797− address = "Berlin",
798− editor = "P. Clote and H. Schwichtenberg",
799− pages = "317--331",
800− year = "2000",
801− url = "citeseer.ist.psu.edu/hancock00interactive.html" }
802−
803−@inproceedings{popeea-resources,
804− author = {Corneliu Popeea and Wei-Ngan Chin},
805− title = {A type system for resource protocol verification and its correctness proof},
806− booktitle = {PEPM '04: Proceedings of the 2004 {ACM} {SIGPLAN} symposium on Partial evaluation and semantics-based program manipulation},
807− year = {2004},
808− isbn = {1-58113-835-0},
809− pages = {135--146},
810− location = {Verona, Italy},
811− doi = {http://doi.{ACM}.org/10.1145/1014007.1014021},
812− publisher = {{ACM} Press},
813− address = {New York, NY, USA},
814− }
815−
816−@inproceedings{sheard-langfuture,
817− author = {Tim Sheard},
818− title = "Languages of the future",
819− booktitle = "{ACM} Conference on Object Orientated Programming Systems, Languages and Applicatioons (OOPSLA'04)",
820− year = "2004"
821−}
822−
823−@inproceedings{ivor,
824− author = {Edwin Brady},
825− title = {{Ivor}, a proof engine},
826− year = {2007},
827− publisher = {Springer-Verlag},
828− series = {LNCS},
829− booktitle = {Implementation and Application of Functional Languages 2006}
830−}
831−
832−@misc{coq-in-coq,
833− author = {Bruno Barras and Benjamin Werner},
834− year = 1997,
835− title = {{Coq} in {Coq}}
836−}
837−
838−@article{hudak-edsl,
839− author = {Paul Hudak},
840− title = {Building Domain-Specific Embedded Languages},
841− year = {1996},
842− month = {December},
843− journal = {{ACM} Computing Surveys},
844− volume = {28A},
845− number = {4}
846−}
847−
848−@inproceedings{concon,
849− author = {Conor McBride and Healfdene Goguen and James McKinna},
850− title = {Some Constructions On Constructors},
851− year = 2005,
852− booktitle = {TYPES 2004},
853− publisher = {Springer},
854− series = {LNCS},
855− volume = {3839}
856−}
857−
858−@InProceedings{Hume-GPCE,
859−author = {K. Hammond and G.J. Michaelson},
860−title = {{Hume: a Domain-Specific Language for Real-Time Embedded Systems}},
861−booktitle = {{Proc. Conf. Generative Programming and Component Engineering (GPCE~'03)}},
862−publisher = {Springer-Verlag},
863−series = {Lecture Notes in Computer Science},
864−year = {2003},
865−}
866−
867−@inproceedings{lcf-milner,
868− author = {Robin Milner},
869− title = {{LCF}: A Way of Doing Proofs with a Machine},
870− booktitle = {Mathematical Foundations of Computer Science 1978},
871− pages = {146-159},
872− year = 1979,
873− series = {LNCS},
874− volume = {64}
875−}
876−
877−
878−@inproceedings{epireloaded,
879− title = {Epigram Reloaded: A Standalone Typechecker for {ETT}},
880− author = {James Chapman and Thorsten Altenkirch and Conor McBride},
881− year = 2006,
882− booktitle = {Trends in Functional Programming 2005},
883− note = {To appear}
884−}
885−
886−@TECHREPORT{why-tool,
887− AUTHOR = {J.-C. Filli\^atre},
888− TITLE = {{Why: a multi-language multi-prover verification tool}},
889− INSTITUTION = {{LRI, Universit\'e Paris Sud}},
890− TYPE = {{Research Report}},
891− NUMBER = {1366},
892− MONTH = {March},
893− YEAR = 2003,
894− URL = {http://www.lri.fr/~filliatr/ftp/publis/why-tool.ps.gz}
895−}
896−
897−@misc{ large-extraction,
898− author = "Lu\'iz Cruz-Filipe and Bas Spitters",
899− title = "Program Extraction from Large Proof Developments",
900− year = 2003,
901− url = "citeseer.ist.psu.edu/cruz-filipe03program.html" }
902−
903−@inproceedings{ fta,
904− author = "Herman Geuvers and Freek Wiedijk and Jan Zwanenburg",
905− title = "A Constructive Proof of the Fundamental Theorem of Algebra without Using the Rationals",
906− booktitle = "{TYPES 2000}",
907− pages = "96--111",
908− year = "2000",
909− url = "citeseer.ist.psu.edu/geuvers01constructive.html" }
910−
911−@article{mckinna-expr,
912− title = {A type-correct, stack-safe, provably correct, expression compiler in {Epigram}},
913− author = {James McKinna and Joel Wright},
914− year = 2007,
915− journal = {Journal of Functional Programming},
916− note = {To appear}
917−}
918−
919−@article{pugh-omega,
920− title = "The {Omega} {Test}: a fast and practical integer programming algorithm for dependence analysis",
921− author = "William Pugh",
922− journal = "Communication of the {ACM}",
923− year = 1992,
924− pages = {102--114}
925−}
926−
927−@misc{four-colour,
928− author = "Georges Gonthier",
929− title = "A computer-checked proof of the {Four Colour Theorem}",
930− year = 2005,
931− howpublished = {\url{http://research.microsoft.com/~gonthier/4colproof.pdf}}}
932−
933−@inproceedings{sparkle,
934− author = "Maarten {de Mol} and Marko {van Eekelen} and Rinus Plasmeijer",
935− title = "Theorem Proving for Functional Programmers",
936− url = "citeseer.ist.psu.edu/654423.html",
937− BOOKTITLE = {Proc. Implementation of Functional Languages (IFL 2002)},
938− publisher = {Springer},
939− series = {LNCS},
940− volume = {2312},
941− year = 2002
942− }
943−
944−@misc{agda,
945− title = {Agda},
946− author = {Catarina Coquand},
947− howpublished= {\url{http://agda.sourceforge.net/}},
948− year = 2005
949−}
950−
951−@misc{cover,
952− title = {Cover Translator},
953− howpublished = {\url{http://coverproject.org/CoverTranslator/}}
954−}
955−
956−@misc{parsec,
957− title = {Parsec, a fast combinator parser},
958− author = {Daan Leijen},
959− year = {2001},
960− howpublished = {\url{http://www.cs.uu.nl/~daan/parsec.html}}
961−}
962−
963−@inproceedings{dtpmsp-gpce,
964− author = {Edwin Brady and Kevin Hammond},
965− title = {A Verified Staged Interpreter is a Verified Compiler},
966− booktitle = {{Proc. Conf. Generative Programming and Component Engineering (GPCE~'06)}},
967− year = 2006
968−}
969−
970−@misc{haddock,
971− title = {Haddock: A {Haskell} Documentation Tool},
972− howpublished = {\url{http://www.haskell.org/haddock/}}
973−}
974−
975−@inproceedings{offshoring,
976− title = {Implicitly Heterogeneous Multi-Stage Programming},
977− author = {Jason Eckhardt and Roumen Kaibachev and Emir Pa\v{s}al\'{i}c and Kedar Swadi and Walid Taha},
978− booktitle = {Proc. 2005 Conf. on Generative Programming and Component Engineering (GPCE 2005)},
979− publisher = {Springer},
980− series = {LNCS},
981− volume = {3676},
982− year = 2005
983−}
984−
985−@misc{alti-partial,
986− title = {Stop thinking about bottoms when writing programs},
987− author = {Thorsten Altenkirch},
988− year = 2006,
989− note = {Talk at BCTCS 2006}
990−}
991−
992−@misc{tarmo-partial,
993− title = {Partiality is an Effect},
994− author = {Tarmo Uustalu},
995− year = 2004,
996− note = {Talk at Dagstuhl workshop on Dependently Typed Progamming}
997−}
998−
999−@inproceedings{McKinnaPOPL06,
1000− author = {James McKinna},
1001− title = {Why dependent types matter},
1002− booktitle = {Proc. {ACM} Symp. on Principles of Programming Languages (POPL 2006)},
1003− year = {2006},
1004− issn = {0362-1340},
1005− pages = {1--1},
1006− doi = {http://doi.{ACM}.org/10.1145/1111320.1111038},
1007−}
1008−
1009−
1010−@inproceedings{leroy-compiler,
1011− title = {Formal Certification of a Compiler Back-end},
1012− author = {Xavier Leroy},
1013− year = 2006,
1014− booktitle = {Principles of Programming Languages 2006},
1015− pages = {42--54},
1016− publisher = {{ACM} Press}
1017−}
1018−
1019−@inproceedings{hutton-exceptions,
1020− title = {Compiling Exceptions Correctly},
1021− year = 2004,
1022− author = {Graham Hutton and Joel Wright},
1023− booktitle = {Mathematics of Program Construction},
1024− publisher = {Springer},
1025− series = {LNCS},
1026− volume = {3125}
1027−}
1028−
1029−@inproceedings{tagless-staged,
1030− title = {Tagless Staged Interpreters for Typed Languages},
1031− year = {2002},
1032− booktitle = {Proc. 2002 International Conf. on Functional Programming ({ICFP} 2002)},
1033− author = {Emir Pa\v{s}al\'{i}c and Walid Taha and Tim Sheard},
1034− publisher = {{ACM}}
1035−}
1036−
1037−@inproceedings{env-classifiers,
1038− title = {Environment Classifiers},
1039− year = 2003,
1040− author = {Walid Taha},
1041− booktitle = {Proc. {ACM} Symp. on Principles of Programming Languages (POPL 2003)},
1042− pages = {26--37},
1043−}
1044−
1045−@inproceedings{dsl-msp,
1046− title = {{DSL} Implementation in {MetaOCaml}, {Template Haskell}, {and C++}},
1047− booktitle = {Domain Specific Program Genearation 2004},
1048− author = {Krzysztof Czarnecki and John O'Donnell and J\"{o}rg Striegnitz and Walid Taha},
1049− publisher = {Springer},
1050− series = {LNCS},
1051− volume = {3016},
1052− year = 2004
1053−}
1054−
1055−@misc{ gadt-extk,
1056− author = {Tim Sheard and James Hook and Nathan Linger},
1057− title = {{GADTs} + Extensible Kinds = Dependent Programming},
1058− year = 2005,
1059− misc = {Submitted to {ICFP} '05}
1060−}
1061−
1062−@INPROCEEDINGS{dt-framework,
1063− TITLE = {A Dependently Typed Framework for Static Analysis of Program Execution Costs},
1064− YEAR = {2006},
1065− BOOKTITLE = {Proc. Implementation of Functional Languages (IFL 2005)},
1066− AUTHOR = {Edwin Brady and Kevin Hammond},
1067− VOLUME = {4015},
1068− SERIES = {LNCS},
1069− PAGES = {74--90},
1070− PUBLISHER = {Springer}
1071−}
1072−
1073−@INPROCEEDINGS{step-counting,
1074− TITLE = {Accurate Step Counting},
1075− YEAR = {2006},
1076− BOOKTITLE = {Proc. Implementation of Functional Languages (IFL 2005)},
1077− AUTHOR = {Catherine Hope and Graham Hutton},
1078− PUBLISHER = {Springer}
1079−}
1080−
1081−@misc{multi-taha,
1082− author = {Walid Taha},
1083− title = {{A Gentle Introduction to Multi-stage Programming}},
1084− year = {2003},
1085− note = {Available from \url{http://www.cs.rice.edu/~taha}},
1086− notnote = {Available from \url{http://www.cs.rice.edu/~taha/publications/journal/dspg04a.pdf}}
1087−}
1088−
1089−@misc{mckinnabrady-phase,
1090− title = {Phase Distinctions in the Compilation of {Epigram}},
1091− year = 2005,
1092− author = {James McKinna and Edwin Brady},
1093− note = {Draft}
1094−}
1095−
1096−@phdthesis{ brady-thesis,
1097− author = {Edwin Brady},
1098− title = {Practical Implementation of a Dependently Typed Functional Programming Language},
1099− year = 2005,
1100− school = {University of Durham}
1101−}
1102−
1103−@phdthesis{ taha-thesis,
1104− author = {Walid Taha},
1105− title = {Multi-stage Programming: Its Theory and Applications},
1106− year = 1999,
1107− school = {Oregon Graduate Inst. of Science and Technology}
1108−}
1109−
1110−@phdthesis{ pasalic-thesis,
1111− author = {Emir Pa\v{s}al\'{i}c},
1112− title = {The Role of Type-Equality in Meta-programming},
1113− year = 2004,
1114− school = {OGI School of Science and Engineering}
1115−}
1116−
1117−@misc{ydtm,
1118− author = {Thorsten Altenkirch and Conor McBride and James McKinna},
1119− title = {Why Dependent Types Matter},
1120− note = {Draft},
1121− year = 2005}
1122−
1123−
1124−@inproceedings { wadler-listless,
1125− author = {Philip Wadler},
1126− title = {Listlessness is better than laziness: {Lazy} evaluation and garbage collection at compile-time},
1127− booktitle = {Proceedings of the 1984 {ACM} Symposium on LISP and functional programming},
1128− year = 1984,
1129− pages = {45--52}
1130−}
1131−
1132−@techreport { gofer-impl,
1133− author = {Mark P. Jones},
1134− title = {The implementation of the Gofer functional programming system},
1135− month = {May},
1136− year = {1994},
1137− number = {YALEU/DCS/RR-1030},
1138− institution = {Yale University}
1139−}
1140−
1141−@techreport { pm-opt1,
1142− author = {Kevin Scott and Norman Ramsey},
1143− title = {When do match-compilation heuristics matter?},
1144− month = {May},
1145− year = {2000},
1146− number = {CS-2000-13},
1147− institution = {Department of Computer Science, University of Virginia}
1148−}
1149−
1150−@inproceedings{ pm-opt2,
1151− author = "Fabrice Le Fessant and Luc Maranget",
1152− title = "Optimizing Pattern Matching",
1153− booktitle = "International Conference on Functional Programming",
1154− pages = "26-37",
1155− year = "2001",
1156− url = "citeseer.ist.psu.edu/lefessant01optimizing.html" }
1157−
1158−@incollection{con-engine,
1159− author = {G\'{e}rard Huet},
1160− title = {The constructive engine},
1161− booktitle = {A Perspective in Theoreticak Computer Science},
1162− publisher = {World Scientific Publishing},
1163− year = {1989},
1164− editor = {R. Narasimhan},
1165− note = {Commemorative Volume for Gift Siromoney},
1166− pages = {38--69}
1167−}
1168−
1169−@inproceedings{gadts,
1170− title = {Simple unification-based type inference for {GADTs}},
1171− author = {Simon {Peyton Jones} and Dimitrios Vytiniotis and Stephanie Weirich and Geoffrey Washburn},
1172− year = {2006},
1173− booktitle = {Proc. 2006 International Conf. on Functional Programming ({ICFP} 2006)}
1174−}
1175−
1176−@misc{wobbly,
1177− author = {Simon {Peyton Jones} and Geoffrey Washburn and Stephanie Weirich},
1178− title = {Wobbly types: type inference for generalised algebraic data types},
1179− year = {2004},
1180− note = {Submitted to POPL 2005}
1181−}
1182−
1183−@misc{epigram-afp,
1184− author = {Conor McBride},
1185− title = {Epigram: Practical Programming with Dependent Types},
1186− year = {2004},
1187− howpublished = {Lecture Notes, International Summer School on Advanced Functional Programming}
1188−}
1189−
1190−@book{ml85,
1191− author = {Per Martin-L\"{o}f},
1192− title = "Intuitionistic Type Theory",
1193− year = "1985",
1194− publisher = "Bibliopolis"
1195−}
1196−
1197−@article{modular-fulllazy,
1198− title = {A Modular Fully Lazy Lambda Lifter in {Haskell}},
1199− author = {Simon {Peyton Jones} and David Lester},
1200− year = {1991},
1201− month = {May},
1202− journal = {Software Practice and Experience},
1203− volume = {21},
1204− number = {5},
1205− pages = {479--506}
1206−}
1207−
1208−@article{ghani-jay95,
1209− author = {Barry Jay and Neil Ghani},
1210− title = {The Virtues of Eta-Expansion},
1211− journal = {Journal of Functional Programming},
1212− year = {1995},
1213− volume = {5},
1214− number = {2},
1215− pages = {135-154},
1216−}
1217−
1218−@misc{nkpat,
1219− author = {Lennart Augustsson},
1220− title = {n+k patterns},
1221− year = {1993},
1222− howpublished = {Message to the haskell mailing list, Mon, 17 May 93}
1223−}
1224−
1225−@article{ danvy98functional,
1226− author = "Olivier Danvy",
1227− title = "Functional Unparsing",
1228− journal = "Journal of Functional Programming",
1229− volume = "8",
1230− number = "6",
1231− pages = "621-625",
1232− year = "1998",
1233− url = "citeseer.ist.psu.edu/danvy98functional.html" }
1234−
1235−@inproceedings{SeveriPoll94,
1236− author = {Paula Severi and Erik Poll},
1237− booktitle = {Logical Foundations of Computing Science, LFCS'94},
1238− editor = {A. Nerode and Yu. V. Matiyasevich},
1239− number = {813},
1240− pages = {316--328},
1241− publisher = {Springer},
1242− series = {LNCS},
1243− title = {{P}ure {T}ype {S}ystems with {D}efinitions},
1244− year = {1994}
1245−}
1246−
1247−@inproceedings{coinductive,
1248− title = {An Application of Co-Inductive Types in Coq: Verification of the Alternating Bit Protocol},
1249− booktitle = {Proceedings of the 1995 Workshop on Types for Proofs and Programs},
1250− series = {LNCS},
1251− year = {1995},
1252− volume = {1158},
1253− pages = {135-152},
1254− publisher = {Springer-Verlag},
1255− author = {Eduardo Gim\'{e}nez}
1256−}
1257−
1258−@book{erlang,
1259− author = "Joe Armstrong and Robert Virding and Claes Wikstr{\"o}m and Mike Williams",
1260− title = "Concurrent Programming in Erlang",
1261− edition = "Second",
1262− publisher = "Prentice-Hall",
1263− year = "1996",
1264− url = "citeseer.ist.psu.edu/armstrong93concurrent.html"
1265−}
1266−
1267−@PhdThesis{alti:phd93,
1268− author = "Thorsten Altenkirch",
1269− title = "Constructions, Inductive Types and Strong Normalization",
1270− school = "University of Edinburgh",
1271− year = "1993",
1272− month = "November",
1273−}
1274−
1275−@inproceedings{coq-modules,
1276− author = "Jacek Chrzaszcz",
1277− title = "Modules in {Coq} Are and Will Be Correct",
1278− year = {2004},
1279− booktitle = {Types for Proofs and Programs 2003},
1280− editor = {Stefano Berardi and Mario Coppo and Ferruccio Damiani},
1281− publisher = {Springer},
1282− volume = {3085}
1283−}
1284−
1285−@inproceedings{comp-polymorphism,
1286− author = "Robert Harper and Greg Morrisett",
1287− title = "Compiling Polymorphism Using Intensional Type Analysis",
1288− year = "1995",
1289− booktitle = "Proceedings of the 22nd {ACM} {SIGPLAN}-SIGACT symposium on Principles of programming languages",
1290− pages = "130 -- 141"
1291−}
1292−
1293−@misc{runtime-loader,
1294− author = "Andre Pang",
1295− title = "{GHC} Runtime Loading",
1296− year = "2004",
1297− howpublished = {Available from \verb+http://www.algorithm.com.au/wiki/hacking/haskell.ghc_runtime_loading+}
1298−}
1299−
1300−@article{mccarthy-lisp,
1301− author = "John McCarthy",
1302− title = "Recursive Functions of Symbolic Expressions and Their Computation By Machine",
1303− year = "1960",
1304− journal = "Communications of the {ACM}",
1305− volume = "3",
1306− number = "4",
1307− pages = "184--195"
1308−}
1309−
1310−@book{stl,
1311− author = " David R. Musser and Atul Saini and Gillmer J. Derge",
1312− title= "The {STL} Tutorial and Reference Guide: {C++} Programming with the Standard Template Library",
1313− year = "2001",
1314− publisher = "Addison Wesley"
1315−}
1316−
1317−@misc{ phase-distinction,
1318− author = "Luca Cardelli",
1319− title = "Phase Distinctions in Type Theory",
1320− howpublished = "Manuscript",
1321− year = "1988",
1322− url = "citeseer.ist.psu.edu/cardelli88phase.html" }
1323−
1324−@book {pierce-types,
1325− author = "Benjamin C. Pierce",
1326− title = "Type and Programming Languages",
1327− year = "2002",
1328− publisher = "MIT Press"
1329−}
1330−
1331−@article{ coqcc,
1332− Author = "Thierry Coquand and G\'{e}rard Huet",
1333− title = "The calculus of constructions",
1334− year = "1988",
1335− journal = "Information and Computation",
1336− volume = "76",
1337− pages = "95--120"
1338−}
1339−
1340−@article{ miller91jlc,
1341− Author = "Dale Miller",
1342− Title = "A Logic Programming Language with Lambda-Abstraction,
1343− Function Variables, and Simple Unification",
1344− Journal = "Journal of Logic and Computation",
1345− Volume = "1",
1346− Number = "4",
1347− Pages = "497-536",
1348− Year = "1991",
1349− URL = "citeseer.ist.psu.edu/miller91logic.html",
1350− URL = "file://ftp.cis.upenn.edu/pub/papers/miller/jlc91.dvi.Z" }
1351−
1352−@article{miller-unity,
1353− author = "Dale Miller",
1354− title = "Unification Under a Mixed Prefix",
1355− journal = "Journal of Symbolic Computation",
1356− volume = "14",
1357− pages = "321--358",
1358− year = 1992
1359−}
1360−
1361−@inproceedings{ cynthia,
1362− author = "Jon Whittle and Alan Bundy and Richard J. Boulton and Helen Lowe",
1363− title = "An {ML} Editor Based on Proofs-As-Programs",
1364− booktitle = "Automated Software Engineering",
1365− pages = "166-173",
1366− year = "1999",
1367− url = "citeseer.ist.psu.edu/whittle99ml.html" }
1368−
1369−
1370−@misc{ewd340,
1371− title={The Humble Programmer},
1372− author={Edsger Dijkstra},
1373− year={1972},
1374− note={Turing Award Lecture, EWD 340}
1375−}
1376−
1377−@misc{fortran,
1378− title={Specifications for the {IBM} Mathematical FORmula TRANslating System, {FORTRAN}},
1379− author={{IBM Applied Science Division}},
1380− key={IBM},
1381− year={1954},
1382− month={November}
1383−}
1384−
1385−@inproceedings{quickcheck,
1386− title = {{QuickCheck}: A Lightweight Tool For Random Testing Of {Haskell} Programs},
1387− author = {Koen Claessen and John Hughes},
1388− year = {2000},
1389− booktitle = {International Conference on Functional Programming}
1390−}
1391−
1392−@inproceedings{currylam,
1393− title = {Functionality in Combinatory Logic},
1394− author = {Haskell Curry},
1395− year = {1934},
1396− booktitle = {Proc. Nat. Acad. Sci, USA},
1397− volume = {20},
1398− pages = {584--590}
1399−}
1400−
1401−@article{churchsimplelam1,
1402− title = {A set of postulates for the foundation of logic},
1403− author = {Alonzo Church},
1404− year = {1932},
1405− journal = {Annals of Mathematics},
1406− volume = {2},
1407− number = {33},
1408− pages = {346--366}
1409−}
1410−
1411−@article{churchsimplelam2,
1412− title = {A set of postulates for the foundation of logic},
1413− author = {Alonzo Church},
1414− year = {1933},
1415− journal = {Annals of Mathematics},
1416− volume = {2},
1417− number = {34},
1418− pages = {839--864}
1419−}
1420−
1421−@article{churchlam,
1422− title = {A Formulation of the Simple Theory of Types},
1423− author = {Alonzo Church},
1424− year = {1940},
1425− journal = {Journal of Symbolic Logic},
1426− volume = {5},
1427− pages = {56--58}
1428−}
1429−
1430−@book{mitchell,
1431− title = {Concepts in Programming Languages},
1432− author = {John C. Mitchell},
1433− year = {2003},
1434− publisher = {Cambridge University Press}
1435−}
1436−
1437−@inproceedings{harrison-hol99,
1438− title = {A Machine-Checked Theory of Floating Point Arithmetic},
1439− year = {1999},
1440− booktitle = {Theorem Proving in Higher Order Logics: 12th International Conference, TP},
1441− pages = {113--130},
1442− author = {John Harrison},
1443− crossref = {hol99}
1444−}
1445−
1446−@inproceedings{c--,
1447− title = {C--: A portable assembly language},
1448− year = {1997},
1449− booktitle = {Workshop on Implementing Functional Languages, St Andrews},
1450− author = {Simon {Peyton Jones} and Thomas Nordin and Dino Oliva},
1451− crossref = {func-imp97}
1452−}
1453−
1454−@proceedings{func-imp97,
1455− title = {Workshop on Implementing Functional Languages, St Andrews},
1456− year = {1997},
1457− editor = {C Clack},
1458− publisher = {Springer-Verlag}
1459−}
1460−
1461−@proceedings{hol99,
1462− volume = {1690},
1463− title = {Theorem Proving in Higher Order Logics: 12th International Conference, TPHOLs'99},
1464− year = {1999},
1465− editor = {Yves Bertot and Gilles Dowek and Andr{\'e} Hirschowitz and Christine Paul},
1466− publisher = {Springer-Verlag},
1467− address = {Nice, France},
1468− series = {LNCS}
1469−}
1470−
1471−@book{mathlogic,
1472− title = {Mathematical Logic and Programming Languages},
1473− year = {1985},
1474− editor = {C.A.R. Hoare and J.C. Shepherdson},
1475− publisher = {Prentice-Hall}
1476−}
1477−
1478−@book{automath,
1479− title = {Selected Papers on Automath},
1480− year = {1994},
1481− editor = {S. Abramsky and J. Barwise and K. Fine and H.J. Keisler and A.S. Troelstr},
1482− publisher = {North-Holland}
1483−}
1484−
1485−@misc{gimps,
1486− howpublished = {http://www.mersenne.org/prime.htm},
1487− title = {Great Internet Mersenne Prime Search}
1488−}
1489−
1490−@misc{haskell-report,
1491− title = {Haskell 98 Language and Libraries --- The Revised Report},
1492− year = {2002},
1493− month = {December},
1494− author = {Simon {Peyton Jones} and others},
1495− howpublished = {Available from \verb+http://www.haskell.org/+}
1496−}
1497−
1498−@inproceedings{cayenne-{ICFP},
1499− author = "Lennart Augustsson",
1500− title = "Cayenne - a Language with Dependent Types",
1501− booktitle = "Proc. 1998 International Conf. on Functional Programming ({ICFP} '98)",
1502− pages = "239--250",
1503− year = "1998",
1504− url = "citeseer.nj.nec.com/augustsson98cayenne.html"
1505−}
1506−
1507−
1508−@misc{equality-cayenne,
1509− howpublished = {\verb+http://www.cs.chalmers.se/~augustss/cayenne/+},
1510− title = {Equality Proofs in Cayenne},
1511− year = {1999},
1512− author = {Lennart Augustsson}
1513−}
1514−
1515−@misc{interp-cayenne,
1516− title = {An exercise in dependent types: A well-typed interpreter},
1517− year = {1999},
1518− author = {Lennart Augustsson and Magnus Carlsson}
1519−}
1520−
1521−@inproceedings{balaa00fixpoint,
1522− title = {Fix-Point Equations for Well-Founded Recursion in Type Theory},
1523− year = {2000},
1524− booktitle = {Theorem Proving in Higher Order Logics},
1525− pages = {1-16},
1526− author = {Antonia Balaa and Yves Bertot}
1527−}
1528−
1529−@inproceedings{isabelle-maple,
1530− title = {Theorems and algorithms: An interface between Isabelle and Maple},
1531− year = {1995},
1532− booktitle = {International Symposium on Symbolic and Algebraic Computation},
1533− author = {Ballarin, C. and Homann, K., and Calmet, J.}
1534−}
1535−
1536−@book{barendregt-num,
1537− title = {The Lambda Calculus, Its Syntax and Semantics},
1538− year = {1984},
1539− publisher = {North-Holland},
1540− author = {Henk Barendregt}
1541−}
1542−
1543−@book{beiler,
1544− title = {Recreations in the Theory of Numbers},
1545− year = {1964},
1546− publisher = {Dover},
1547− author = {Albert H. Beiler}
1548−}
1549−
1550−@article{multidigit,
1551− journal = {Advances in Applied Mathematics},
1552− title = {Multidigit Multiplication for Mathematicians},
1553− year = {1998},
1554− author = {Daniel J. Bernstein}
1555−}
1556−
1557−@article{buhler-fox,
1558− journal = {{ACM} Crossroads 2.1.},
1559− month = {September},
1560− title = {The Fox project: A language-structured approach to networking software.},
1561− year = {1995},
1562− author = {Buhler, J.},
1563− note = {Available at http://www.{ACM}.org/crossroads/xrds2-1/foxnet.html}
1564−}
1565−
1566−@techreport{burstall91,
1567− title = {Computer Assisted Proof for Mathematics: an Introduction Using the \textsc{Lego} Proof System},
1568− year = {1991},
1569− institution = {University of Edinburgh},
1570− author = {Rod Burstall}
1571−}
1572−
1573−@article{plastic,
1574− title = {An Implementation of {LF} with Coercive Subtyping and Universes},
1575− author = {Paul Callaghan and Zhaohui Luo},
1576− journal = {Journal of Automated Reasoning},
1577− volume = {27},
1578− number = {1},
1579− pages = {3--27},
1580− year = {2001}
1581−}
1582−
1583−@article{coercive,
1584− title = {Coercive subtyping},
1585− author = {Zhaohui Luo},
1586− journal = {J. Logic Comput.},
1587− volume = {9},
1588− number = {1},
1589− year = {1991},
1590− pages = {105--130}
1591−}
1592−
1593−@inproceedings{calmet-homann,
1594− title = {Classification of communication and cooperation mechanisms for logical and symbolic computation systems},
1595− year = {1996},
1596− booktitle = {Proceedings of the First International Workshop 'Frontiers of Combining S},
1597− pages = {133-146},
1598− publisher = {Kluwer},
1599− author = {J. Calmet and K. Homann}
1600−}
1601−
1602−@techreport{comm-proofs,
1603− title = {On Communicating Proofs in Interactive Mathematical Documents},
1604− year = {2000},
1605− institution = {Eindhoven University of Technology},
1606− author = {Olga Caprotti and Martijn Oostdijk}
1607−}
1608−
1609−@article{prime2999,
1610− title = {How to formally and efficiently prove Prime(2999)},
1611− year = {2001},
1612− author = {Olga Caprotti and Martijn Oostdijk},
1613− journal = {Symbolic Computation and Automated Reasoning},
1614− pages = {114--125}
1615−}
1616−
1617−@book{church-num,
1618− title = {The Calculi of Lambda-Conversion},
1619− year = {1941},
1620− publisher = {Princeton University Press},
1621− author = {Alonzo Church}
1622−}
1623−
1624−@book{nuprl86,
1625− title = {Implementing Mathematics with the NuPrl Proof Development System},
1626− year = {1986},
1627− publisher = {Prentice-Hall},
1628− address = {NJ},
1629− author = {Constable, Robert L. and others}
1630−}
1631−
1632−@book{conway,
1633− title = {On Numbers and Games},
1634− year = {1976},
1635− publisher = {Academic Press},
1636− author = {J.H. Conway}
1637−}
1638−
1639−@misc{coq-manual,
1640− howpublished = {\verb+http://coq.inria.fr/+},
1641− title = {The {Coq} Proof Assistant --- Reference Manual},
1642− year = {2009},
1643− author = {{Coq Development Team}}
1644−}
1645−
1646−@misc{tt-prog,
1647− month = {June},
1648− title = {Type Theory and Programming},
1649− year = {1994},
1650− author = {Thierry Coquand and Bengt Nordstr\"{o}m and Jan M. Smith and Bj\"{o}rn von Sydow}
1651−}
1652−
1653−@book{func-appr,
1654− title = {The Functional Approach to Programming},
1655− year = {1998},
1656− publisher = {Cambridge University Press},
1657− author = {Guy Cousineau and Michel Mauny}
1658−}
1659−
1660−@misc{ibmspec,
1661− howpublished = {http://www2.hursley.ibm.com/decimal/},
1662− month = {January},
1663− title = {Standard Decimal Arithmetic Specification},
1664− year = {2001},
1665− author = {Mike Cowlishaw},
1666− note = {\copyright IBM Corporation 2001}
1667−}
1668−
1669−@book{dummett,
1670− title = {Elements of Intuitionism},
1671− year = {2000},
1672− edition = {2nd},
1673− publisher = {Oxford: Clarendon},
1674− author = {Michael A.E. Dummet}
1675−}
1676−
1677−@article{dybjer94,
1678− title = {Inductive Families},
1679− year = {1994},
1680− author = {Peter Dybjer},
1681− journal = {Formal Aspects Of Computing},
1682− volume = {6},
1683− pages = {440--465}
1684−}
1685−
1686−@misc{octave,
1687− howpublished = {http://www.octave.org/},
1688− month = {February},
1689− title = {GNU Octave -- A high-level interactive language for numerical computations},
1690− year = {1997},
1691− author = {John W. Eaton}
1692−}
1693−
1694−@book{comp-methods,
1695− title = {Computing methods for scientists and engineers},
1696− year = {1968},
1697− publisher = {Oxford : Clarendon Press},
1698− author = {L. Fox and D.F. Mayers}
1699−}
1700−
1701−@misc{guile,
1702− howpublished = {http://www.gnu.org/software/guile/guile.html},
1703− title = {Guile -- Project GNU's extension language},
1704− year = {2001},
1705− author = {{Free Software Foundation}}
1706−}
1707−
1708−@article{need-dep,
1709− journal = {Journal of Functional Programming},
1710− number = {4},
1711− volume = {10},
1712− title = {Do we need dependent types?},
1713− year = {2000},
1714− pages = {409-415},
1715− author = {Daniel Fridlender and Mia Indrika}
1716−}
1717−
1718−@book{primes-programming,
1719− title = {Primes and Programming -- An Introduction to Number Theory with Computing},
1720− year = {1993},
1721− publisher = {Cambridge University Press},
1722− author = {Peter Giblin}
1723−}
1724−
1725−@misc{rec-coq,
1726− month = {May},
1727− title = {A Tutorial on Recursive Types in \textsc{Coq}},
1728− year = {1998},
1729− author = {Eduardo Gim\'{e}nez}
1730−}
1731−
1732−@article{goldberg91,
1733− journal = {{ACM} Computing Surveys},
1734− number = {1},
1735− volume = {23},
1736− title = {What every computer scientist should know about floating point arithmetic},
1737− year = {1991},
1738− pages = {5-48},
1739− author = {D. Goldberg}
1740−}
1741−
1742−@article{binary-lambda,
1743− journal = {Journal of Functional Programming},
1744− number = {6},
1745− volume = {10},
1746− title = {An adequate and efficient left associated binary numeral system in the $\lambda$-calculus},
1747− year = {2000},
1748− author = {Mayer Goldberg}
1749−}
1750−
1751−@book{hol,
1752− title = {Introduction to HOL},
1753− year = {1993},
1754− publisher = {Cambridge University Press},
1755− author = {M. Gordon and T. Melham}
1756−}
1757−
1758−@misc{gmp,
1759− howpublished = {Available from \verb+http://www.swox.com/gmp/manual/+},
1760− title = {The {GNU Multiple Precision} Arithmetic Library 4.1.3 --- Manual},
1761− year = {2004},
1762− author = {Torbj\"{o}rn Granlund and others}
1763−}
1764−
1765−@article{harrison-fmsd94,
1766− journal = {Formal Methods in System Design},
1767− volume = {5},
1768− title = {Constructing the Real Numbers in {HOL}},
1769− year = {1994},
1770− pages = {35--59},
1771− author = {John Harrison}
1772−}
1773−
1774−@book{harrison-thesis,
1775− title = {Theorem Proving with the Real Numbers},
1776− year = {1998},
1777− publisher = {Springer-Verlag},
1778− author = {John Harrison}
1779−}
1780−
1781−@techreport{hol-maple,
1782− title = {Reasing about the Reals: the marriage of HOL and Maple},
1783− year = {1993},
1784− institution = {University of Cambridge Computer Laboratory},
1785− author = {John Harrison and Laurent Th\'{e}ry}
1786−}
1787−
1788−@misc{coq-tutorial,
1789− howpublished = {http://pauillac.inria.fr/coq},
1790− title = {The \textsc{Coq} Proof Assistant - A Tutorial},
1791− author = {G\'{e}rard Huet and Gilles Kahn and Christine Paulin-Mohring}
1792−}
1793−
1794−@misc{restr-haskell,
1795− howpublished = {http://citeseer.nj.nec.com/253599.html},
1796− month = {September},
1797− title = {Restricted Data Types in Haskell},
1798− year = {1999},
1799− author = {John Hughes}
1800−}
1801−
1802−@misc{javadec,
1803− howpublished = {http://www2.hursley.ibm.com/decimalj/decimald.html},
1804− month = {September},
1805− title = {Decimal Arithmetic for Java -- a Proposal},
1806− year = {2000},
1807− author = {{IBM Corporation}}
1808−}
1809−
1810−@misc{ieee754,
1811− title = {{IEEE} Standard for Binary Floating Point Arithmetic},
1812− year = {1985},
1813− author = {{IEEE Standard 754}}
1814−}
1815−
1816−@misc{ieee854,
1817− title = {IEEE Standard for Radix-Independent Floating-Point Arithmetic},
1818− year = {1987},
1819− author = {{IEEE Standard 854}}
1820−}
1821−
1822−@inproceedings{jon91,
1823− title = {Completing the Rational and Metric Spaces in \textsc{Lego}},
1824− year = {1991},
1825− booktitle = {Proceedings of the Second Workshop on Logical Frameworks},
1826− author = {Claire Jones}
1827−}
1828−
1829−@misc{ typinghaskell,
1830− author = "Mark Jones",
1831− title = "Typing {Haskell} in {Haskell}",
1832− howpublished = "In Haskell Workshop, September 1999.",
1833− year = "1999",
1834− url = "citeseer.ist.psu.edu/article/jones99typing.html" }
1835−
1836−@article{karatsuba,
1837− journal = {Soviet Physics-Doklady},
1838− volume = {7},
1839− title = {Multiplication of multidigit numbers by automata},
1840− year = {1963},
1841− pages = {595--596},
1842− author = {A. Karatsuba and Y. Ofman}
1843−}
1844−
1845−@book{knuth2,
1846− volume = {2},
1847− title = {The Art of Computer Programming - Seminumerical Algorithms},
1848− year = {1969},
1849− publisher = {Addison Wesley},
1850− author = {Donald E. Knuth}
1851−}
1852−
1853−@article{next700,
1854− journal = {Communications of the {ACM}},
1855− number = {3},
1856− month = {March},
1857− volume = {9},
1858− title = {The next 700 programming languages},
1859− year = {1966},
1860− author = {P.J. Landin}
1861−}
1862−
1863−@techreport{luo-spec,
1864− month = {January},
1865− title = {Program Specification and Data Refinement in Type Theory},
1866− year = {1993},
1867− institution = {Department of Computer Science, University of Edinburgh},
1868− author = {Zhaohui Luo}
1869−}
1870−
1871−@phdthesis{luo90,
1872− school = {University of Edinburgh},
1873− title = {An Extended Calculus Of Constructions},
1874− year = {1990},
1875− author = {Zhaohui Luo}
1876−}
1877−
1878−@techreport{lego-manual,
1879− title = {\textsc{Lego} Proof Development System: User's Manual},
1880− year = {1992},
1881− institution = {Department of Computer Science, University of Edinburgh},
1882− author = {Zhaohui Luo and Robert Pollack}
1883−}
1884−
1885−@inproceedings{alf,
1886− title = {The {ALF} proof editor and its proof engine},
1887− year = {1994},
1888− booktitle = {Formal Proceeding of the 1993 Workshop on Types for Proofs and Programs},
1889− author = {Lena Magnusson and Bengt N\"{o}rdstrom}
1890−}
1891−
1892−@misc{happy,
1893− howpublished = {http://www.haskell.org/happy/},
1894− title = {Happy User Guide},
1895− year = {2001},
1896− author = {Simon Marlow and Andy Gill}
1897−}
1898−
1899−@inproceedings{generic-haskell,
1900− title = {Generic Haskell, Specifically},
1901− author = {Dave Clarke and Andres L\"{o}h},
1902− editor = {Jeremy Gibbons and Johan Jeuring},
1903− booktitle = {Proceedings of the IFIP TC2 Working Conference on Generic Programming},
1904− year = {2002},
1905− publisher = {Kluwer Academic Publishers},
1906− pages = {21--48}
1907−}
1908−
1909−@article{faking-it,
1910− title = {Faking It -- Simulating Dependent Types in {Haskell}},
1911− year = {2002},
1912− author = {Conor McBride},
1913− journal = {Journal of Functional Programming},
1914− volume = {12},
1915− number = {4+5},
1916− pages = {375--392}
1917−}
1918−
1919−@misc{mcbride-inverting,
1920− title = {Inverting Inductively Defined Relations in \textsc{Lego}},
1921− year = {1996},
1922− author = {Conor McBride}
1923−}
1924−
1925−@phdthesis{mcbride-thesis,
1926− month = {May},
1927− school = {University of Edinburgh},
1928− title = {Dependently Typed Functional Programs and their proofs},
1929− year = {2000},
1930− author = {Conor McBride}
1931−}
1932−
1933−@article{mcbride-unification,
1934− title = {First-Order Unification by Structural Recursion},
1935− year = {2003},
1936− author = {Conor McBride},
1937− journal = {Journal of Functional Programming},
1938− volume = {13},
1939− number = {6},
1940− pages = {1061--1075}
1941−}
1942−
1943−@misc{mckinna-pollack,
1944− howpublished = {Kluwer Academic Publishers},
1945− title = {Some Lambda Calculus and Type Theory formalized},
1946− year = {1998},
1947− author = {James McKinna and Robert Pollack}
1948−}
1949−
1950−@book{num-theory,
1951− title = {An Introduction to the Theory of Numbers},
1952− year = {1980},
1953− publisher = {John Wiley and Sons},
1954− author = {Ivan Niven and Herbert S. Zuckerman}
1955−}
1956−
1957−@book{prog-mltt,
1958− title = {Programming in Martin-L\"{o}f's Type Theory -- An Introduction},
1959− year = {1990},
1960− publisher = {Oxford University Press},
1961− author = {Bengt Nordstr\"{o}m and Kent Petersson and Jan M. Smith},
1962− note = {Out of print. Available from http://www.cs.chalmers.se/Cs/Research/Logic}
1963−}
1964−
1965−@book{okasaki,
1966− title = {Purely Functional Data Structures},
1967− year = {1998},
1968− publisher = {Cambridge University Press},
1969− author = {Chris Okasaki}
1970−}
1971−
1972−@book{arith-systems,
1973− title = {Computer Arithmetic Systems},
1974− year = {1994},
1975− publisher = {Prentice-Hall},
1976− author = {Amos R. Omondi}
1977−}
1978−
1979−@book{pj-imp,
1980− title = {The Implementation of Functional Programming Languages},
1981− year = {1987},
1982− publisher = {Prentice-Hall},
1983− author = {Simon {Peyton Jones}}
1984−}
1985−
1986−@book{cp-bjc,
1987− title = {Computational Numerical Methods},
1988− year = {1986},
1989− publisher = {John Wiley and Sons},
1990− author = {C. Phillips and B. Cornelius}
1991−}
1992−
1993−@book{nag,
1994− title = {The NAG Library: a beginner's guide},
1995− year = {1986},
1996− publisher = {Oxford : Clarendon Press},
1997− author = {Jen Phillips}
1998−}
1999−
2000−@misc{believe,
2001− month = {September},
2002− title = {How to Believe a Machine-Checked Proof},
2003− year = {1996},
2004− author = {Robert Pollack}
2005−}
2006−
2007−@phdthesis{pollack94,
2008− school = {University of Edinburgh},
2009− title = {The Theory of LEGO -- A Proof Checker for the Extended Calculus of Constructions},
2010− year = {1994},
2011− author = {Robert Pollack}
2012−}
2013−
2014−@inproceedings{intel-bug,
2015− series = {LNCS},
2016− volume = {915},
2017− title = {Anatomy of the Pentium Bug},
2018− publisher = {Springer-Verlag},
2019− year = {1995},
2020− pages = {97--107},
2021− author = {V.R. Pratt}
2022−}
2023−
2024−@book{maple,
2025− title = {The Maple Handbook: Maple V Release 4},
2026− year = {1996},
2027− publisher = {Springer},
2028− author = {Darren Redfern}
2029−}
2030−
2031−@book{crypto,
2032− title = {Applied Cryptography: protocols, algorithms and source code in C.},
2033− year = {1996},
2034− publisher = {Wiley},
2035− author = {Bruce Schneier}
2036−}
2037−
2038−@article{adts,
2039− journal = {Mathematical Structures in Computer Science},
2040− number = {2},
2041− volume = {10},
2042− title = {On lists and other abstract data types in the calculus of construction},
2043− year = {2000},
2044− pages = {261-276},
2045− author = {Jonathan P. Seldin}
2046−}
2047−
2048−@article{seldin97,
2049− journal = {Annals of Pure and Applied Logic},
2050− number = {1},
2051− month = {January},
2052− volume = {83},
2053− title = {On the proof theory of Coquand's calculus of constructions},
2054− year = {1997},
2055− pages = {23--101},
2056− author = {Jonathan P. Seldin}
2057−}
2058−
2059−@article{wichmann,
2060− journal = {The Computer Journal},
2061− volume = {32},
2062− title = {Towards a Formal Specification of Floating Point},
2063− year = {1989},
2064− pages = {432-436},
2065− author = {B.A. Wichmann}
2066−}
2067−
2068−@book{mathematica,
2069− title = {Mathematica : a system for doing mathematics by computer},
2070− year = {1991},
2071− publisher = {Addison Wesley},
2072− author = {Stephen Wolfram}
2073−}
2074−
2075−@inproceedings{xi-imp,
2076−author = "Hongwei Xi",
2077−title = {{Imperative Programming with Dependent Types}},
2078−booktitle = "Proceedings of 15th {IEEE} Symposium on Logic in Computer Science",
2079−year = 2000,
2080−month = "June",
2081−address = "Santa Barbara",
2082−pages = "375--387"
2083−}
2084−
2085−@phdthesis{xi-thesis,
2086− month = {December},
2087− school = {Department of Mathematical Sciences, Carnegie Mellon University},
2088− title = {Dependent Types in Practical Programming},
2089− year = {1998},
2090− author = {Hongwei Xi}
2091−}
2092−
2093−
2094−@techreport{dtal,
2095−author = {Hongwei Xi and Robert Harper},
2096−title = {A Dependently Typed Assembly Language},
2097−institution = {Computer Science and Engineering Department, Oregon Graduate Institute},
2098−year = 1999,
2099−number = {OGI-CSE-99-008},
2100−month = {July},
2101−}
2102−
2103−@misc{bignum-cmp,
2104− month = {February},
2105− title = {Comparison of three public-domain multiprecision libraries: BigNum, Gmp and Pari},
2106− year = {1998},
2107− author = {Paul Zimmerman}
2108−}
2109−
2110−@book{perl,
2111− title = {Programming Perl},
2112− author = {Larry Wall and Tom Christiansen and Jon Orwant},
2113− year = {2000},
2114− edition = {3rd},
2115− publisher = {O'Reilly}
2116−}
2117−
2118−@misc{python,
2119− howpublished = {http://www.python.org/doc/current/tut/tut.html},
2120− month = {April},
2121− title = {Python Tutorial},
2122− year = {2001},
2123− author = {Guido van {Rossum} and Fred L. {Drake, Jr}}
2124−}
2125−
2126−@book{logic,
2127− title = {The Language of First Order Logic},
2128− year = {1992},
2129− publisher = {CSLI Lecture Notes},
2130− author = {Jon Barwise and John Etchemendy}
2131−}
2132−
2133−@book{haskell,
2134− title = {Haskell -- The Craft of Functional Programming},
2135− year = {1999},
2136− publisher = {Addison Wesley},
2137− author = {Simon Thompson}
2138−}
2139−
2140−@inproceedings{coq-hol,
2141− title = {A Comparative Study of Coq and HOL},
2142− year = {1997},
2143− booktitle = {Theorem Proving in Higher Order Logics},
2144− pages = {323-337},
2145− author = {Vincent Zammit}
2146−}
2147−
2148−@misc{gay90,
2149− month = {November},
2150− title = {Correctly Rounded Binary-Decimal and Decimal-Binary Conversions},
2151− year = {1990},
2152− author = {David M. Gay},
2153− note = {AT&T Bell Laboratories, Numerical Analysis Manuscript 90-10}
2154−}
2155−
2156−@article{hughes-matters,
2157− journal = {Computer Journal},
2158− number = {2},
2159− volume = {32},
2160− title = {Why Functional Programming Matters},
2161− year = {1989},
2162− pages = {98--107},
2163− author = {J. Hughes}
2164−}
2165−
2166−@inproceedings{proofpointing,
2167− title = {Proof by Pointing},
2168− year = {1994},
2169− booktitle = {Proceedings of the International Symposium on Theoretical Aspects of Computer So},
2170− pages = {141--160},
2171− editor = {M. Hagiya and J. C. Mitchell},
2172− publisher = {Springer-Verlag},
2173− series = {LNCS},
2174− volume = {789},
2175− address = {Sendai, Japan},
2176− author = {Yves Bertot and Gilles Kahn and Laurent Th{\'e}ry}
2177−}
2178−
2179−@misc{inductive-coq,
2180− month = {December},
2181− title = {Inductive Definitions in the System Coq -- Rules and Properties},
2182− year = {1992},
2183− author = {Christine Paulin-Mohring}
2184−}
2185−
2186−@misc{leiserson98,
2187− month = {July},
2188− title = {Using de Bruijn Sequences to Index a 1 in a Computer Word},
2189− year = {1998},
2190− author = {{Charles E. Leiserson} and {Harald Prokop} and {Keith H. Randall}}
2191−}
2192−
2193−@inproceedings{proofchecking,
2194− title = {A two-level approach towards lean proof-checking},
2195− year = {1996},
2196− booktitle = {TYPES},
2197− pages = {16--35},
2198− author = {G. Barthe and M.P.J. Ruys and H.P. Barendregt}
2199−}
2200−
2201−@inproceedings{congruence,
2202− title = {Congruence Types},
2203− year = {1995},
2204− booktitle = {CSL},
2205− pages = {36--51},
2206− author = {Gilles Barthe and Herman Geuvers}
2207−}
2208−
2209−@phdthesis{geuvers-thesis,
2210− title = {Logic and Type Systems},
2211− author = {Herman Geuvers},
2212− year = 1993,
2213− school = {Katholieke Universiteit Nijmegen}
2214−}
2215−
2216−@techreport{multiple-values,
2217− title = {Multiple Values in {Standard ML}},
2218− year = {1994},
2219− number = {94-312},
2220− institution = {LFCS, Dept of Computer Science, University of Edinburgh},
2221− author = {Kevin Mitchell}
2222−}
2223−
2224−@inproceedings{oracle-checking,
2225− month = {January},
2226− title = {Oracle-Based Checking of Untrusted Software},
2227− year = {2001},
2228− booktitle = {Proceedings of the 28th {ACM} Symposium on Principles of Programming Languages},
2229− pages = {142--154},
2230− author = {{George C. Necula} and {S.P. Rahul}}
2231−}
2232−
2233−@article{adams93jfp,
2234− journal = {Journal of Functional Programming},
2235− number = {4},
2236− volume = {3},
2237− title = {Efficient Sets -- A Balancing Act},
2238− year = {1993},
2239− pages = {553--561},
2240− author = {Stephen Adams}
2241−}
2242−
2243−@inproceedings{hughes-sized,
2244− title = {Proving the Correctness of Reactive Systems Using Sized Types},
2245− year = {1996},
2246− booktitle = {Proceedings of the 23rd {ACM} {SIGPLAN}-SIGACT symposium on Principles of programmin},
2247− pages = {410--423},
2248− author = {John Hughes and Lars Pareto and Amr Sabry}
2249−}
2250−
2251−@inproceedings{whittle99ml,
2252− title = {An {ML} Editor Based on Proofs-As-Programs},
2253− year = {1999},
2254− booktitle = {Automated Software Engineering},
2255− pages = {166--173},
2256− author = {Jon Whittle and Alan Bundy and Richard J. Boulton and Helen Lowe}
2257−}
2258−
2259−@book{efp-typeinf,
2260− title = {Elements of Functional Programming},
2261− year = {1989},
2262− publisher = {Addison-Wesley},
2263− author = {Chris Reade},
2264− series = {International Computer Science Series}
2265−}
2266−
2267−@incollection{ wadler-views,
2268− author = "Philip Wadler",
2269− title = "Views: {A} Way for Pattern Matching to Cohabit with Data Abstraction",
2270− booktitle = "Proceedings, 14th Symposium on Principles of Programming Languages",
2271− publisher = "Association for Computing Machinery",
2272− editor = "Steve Munchnik",
2273− pages = "307--312",
2274− year = "1987",
2275− url = "citeseer.nj.nec.com/wadler87views.html" }
2276−
2277−@article{ coquand-checking,
2278− author = "Thierry Coquand",
2279− title = "An Algorithm for Type-Checking Dependent Types",
2280− journal = "Science of Computer Programming",
2281− volume = "26",
2282− number = "1-3",
2283− pages = "167-177",
2284− year = "1996",
2285− url = "citeseer.nj.nec.com/coquand96algorithm.html" }
2286−
2287−@misc{coquand-pm,
2288− author = "Thierry Coquand",
2289− title = "Pattern Matching with Dependent Types",
2290− year = "1992",
2291− howpublished = "Available from \verb+http://www.cs.chalmers.se/~coquand/type.html+"
2292−}
2293−
2294−@misc{pollack-records,
2295− month = {August},
2296− title = {Dependently Typed Records for Representing Mathematical Structure},
2297− year = {2000},
2298− author = {Robert Pollack}
2299−}
2300−
2301−@article{checking-betarte,
2302− journal = {Journal of Functional Programming},
2303− number = {2},
2304− month = {March},
2305− volume = {10},
2306− title = {Type checking dependent (record) types and subtyping},
2307− year = {2000},
2308− pages = {137--166},
2309− author = {Gustavo Betarte}
2310−}
2311−
2312−
2313−@article{ gcode,
2314− author = "Thomas Johnsson",
2315− title = "Efficient Compilation of Lazy Evaluation",
2316− booktitle = "Proceedings of the {{ACM}} {{SIGPLAN}}'84 Symposium on Compiler Con struction",
2317− journal = "{SIGPLAN} Notices",
2318− volume = "19",
2319− number = "6",
2320− month = "June",
2321− publisher = "{ACM} Press",
2322− pages = "58--69",
2323− year = "1984",
2324− url = "citeseer.nj.nec.com/johnsson84efficient.html" }
2325−
2326−@misc{kamareddine01,
2327− month = {February},
2328− title = {Reviewing the classical and the de Bruijn notation for $\lambda$-calculus and pure type systems},
2329− year = {2001},
2330− author = {Fairouz Kamareddine}
2331−}
2332−
2333−@book{prooftheory,
2334− title = {Basic Proof Theory},
2335− year = {1996},
2336− publisher = {Cambridge University Press},
2337− author = {A.S. Troelstra and H. Schwichtenberg},
2338− series = {Cambridge Tracts in Theoretical Computer Science}
2339−}
2340−
2341−@misc{nbe_staged,
2342− title = {Integrating Normalization-by-Evaluation into a Staged Programming Language},
2343− year = {1998},
2344− author = {Tim Sheard}
2345−}
2346−
2347−@inproceedings{nbe2,
2348− title = {Normalization by evaluation},
2349− year = {1998},
2350− author = {Ulrich Berger and Matthias Eberl and Helmut Schwichtenberg},
2351− booktitle = {Prospects for Hardware Foundations 1998},
2352− pages = {117--137},
2353− series = {LNCS}
2354−}
2355−
2356−
2357−
2358−@misc{rtcg_jfp,
2359− title = {Compiling for Run-time Code Generation},
2360− year = {2000},
2361− author = {Frederick Smith and Dan Grossman and Greg Morrisett and Luke Hornof and Trevor J},
2362− note = {Under consideration for J. Functional Programming}
2363−}
2364−
2365−@phdthesis{fredsmith_thesis,
2366− month = {January},
2367− school = {Cornell University},
2368− title = {Certified Run-time Code Generation},
2369− year = {2002},
2370− author = {Frederick Smith}
2371−}
2372−
2373−@inproceedings{xi_arraybounds,
2374−author = "Hongwei Xi and Frank Pfenning",
2375−title = {Eliminating Array Bound Checking through Dependent Types},
2376−booktitle = "Proceedings of {ACM} {SIGPLAN} Conference on Programming Language Design and Implementation",
2377−year = 1998,
2378−month = "June",
2379−address = "Montreal",
2380−pages = "249--257",
2381−}
2382−
2383−@inproceedings{xi_deadcode,
2384−author = "Hongwei Xi",
2385−title = {Dead Code Elimination through Dependent Types},
2386−booktitle = "The First International Workshop on Practical Aspects of Declarative Languages",
2387−year = 1999,
2388−month = "January",
2389−address = "San Antonio",
2390−pages = "228--242"
2391−}
2392−
2393−@book{compilers,
2394− title = {Compilers --- Principles, Techniques and Tools},
2395− year = {1986},
2396− publisher = {Addison-Wesley},
2397− author = {Alfred Aho and Ravi Sethi and Jeffrey Ullman}
2398−}
2399−
2400−@inproceedings{nhc,
2401− title = {Highlights from nhc: A space efficient {Haskell} Compiler},
2402− year = {1995},
2403− author = "Niklas R{\"o}jemo",
2404− booktitle = "Functional Programming Languages and Computer Architecture",
2405− pages = "282--292"
2406−}
2407−
2408−
2409−@misc{mlmatch,
2410− title = {SML/NJ Match Compiler Notes},
2411− year = {1992},
2412− author = {William Aitken}
2413−}
2414−
2415−@misc{mlmatch_sestoft,
2416− title = {ML pattern match compilation and partial evaluation},
2417− year = {1992},
2418− author = {Peter Sestoft}
2419−}
2420−
2421−@inproceedings{compiledstrongreduction,
2422− title = {A Compiled Implementation of Strong Reduction},
2423− year = {2002},
2424− author = {Benjamin Gr\'{e}goire and Xavier Leroy},
2425− booktitle = {Proc. 2002 International Conf. on Functional Programming ({ICFP} 2002)},
2426− pages = {235--246}
2427−}
2428−
2429−@misc{tclhaskell,
2430− howpublished = {http://www.dcs.gla.ac.uk/~meurig/TclHaskell/usermanual.html},
2431− month = {August},
2432− title = {TclHaskell - User Manual},
2433− year = {1999},
2434− author = {Meurig Sage}
2435−}
2436−
2437−
2438−@InProceedings{nbe-cat,
2439− author = "Thorsten Altenkirch and Martin Hofmann and Thomas Streicher",
2440− title = "Categorical reconstruction of a reduction free
2441− normalization proof",
2442− year = "1995",
2443− booktitle = "Category Theory and Computer Science",
2444− editor = {David Pitt and David E. Rydeheard and Peter Johnstone},
2445− series = {LNCS},
2446− volume = {953},
2447− pages = {182-199}
2448−}
2449−
2450−@inproceedings{presburgerEFSM,
2451− title = {A Comparison of Presburger Engines for EFSM Reachability},
2452− year = {1998},
2453− booktitle = {Computer Aided Verification '98},
2454− pages = {280--292},
2455− author = {Thomas R. Shiple and James H. Kukula and Rajeev K. Ranjan}
2456−}
2457−
2458−@misc{typesafecast,
2459− title = {Type-Safe Cast},
2460− year = {2000},
2461− author = {Stephanie Weirich}
2462−}
2463−
2464−@phdthesis{grobauer-thesis,
2465− school = {University of Aarhus},
2466− title = {Topics in Semantics Based Program Manipulation},
2467− year = {2001},
2468− author = {Bernd Grobauer}
2469−}
2470−
2471−@misc{monads-moggi,
2472− title = {Computational Lambda Calculus and Monads},
2473− year = {1989},
2474− author = {Eugenio Moggi}
2475−}
2476−
2477−@article{gmp-proof,
2478− title = {A proof of {GMP} square root},
2479− year = {2002},
2480− journal = {Journal of Automated Reasoning},
2481− volume = {29},
2482− pages = {225--252},
2483− author = {Yves Bertot and Nicolas Magaud and Paul Zimmerman}
2484−}
2485−
2486−@article{F-tal,
2487− journal = {{ACM} Transactions on Programming Languages and Systems},
2488− number = {3},
2489− month = {May},
2490− volume = {21},
2491− title = {From {System F} to Typed Assembly Language},
2492− year = {1999},
2493− pages = {528--569},
2494− author = {Greg Morrisett and David Walker and Karl Crary and Neal Glew}
2495−}
2496−
2497−@techreport{nbe-rtcg,
2498− month = {December},
2499− title = {Strong Normalization by Type-Directed Partial Evaluation and Run-Time Code Generation},
2500− year = {1997},
2501− institution = {BRICS},
2502− author = {Vincent Balat and Oliver Danvy}
2503−}
2504−
2505−@misc{yong-schemata,
2506− howpublished = {http://www.dur.ac.uk/yong.luo/},
2507− title = {A Methodology for Implementing Inductive Schemata},
2508− year = {2002},
2509− author = {Yong Luo and Zhaohui Luo}
2510−}
2511−
2512−@inproceedings{harper93,
2513− title = {Explicit Polymorphism and CPS Conversion},
2514− year = {1993},
2515− booktitle = {20th {ACM} {SIGPLAN}-SIGACT Symposium on Principles of Programming Languages},
2516− pages = {206--219},
2517− publisher = {{ACM} Press, New York, NY, USA},
2518− author = {Robert Harper and Mark Lillibridge}
2519−}
2520−
2521−@techreport{backends,
2522− month = {November},
2523− title = {Functional Back-Ends within the Lambda-Sigma Calculus},
2524− year = {1996},
2525− institution = {INRIA},
2526− author = {Th\'{e}r\`{e}se Hardin and Luc Maranget and Bruno Pagano}
2527−}
2528−
2529−@article{stg,
2530− title = {Implementing lazy functional languages on stock hardware -- the {Spineless Tagless G-machine}},
2531− year = {1992},
2532− journal = {Journal of Functional Programming},
2533− volume = {2},
2534− number = {2},
2535− pages = {127--202},
2536− month = {April},
2537− author = {Simon {Peyton Jones}}
2538−}
2539−
2540−@article{debruijn,
2541− journal = {Indagationes Mathematicae},
2542− volume = {34},
2543− title = {Lambda calculus notation with nameless dummies},
2544− year = {1972},
2545− pages = {381--392},
2546− author = {N.G. de Bruijn}
2547−}
2548−
2549−@book{assembly,
2550− month = {January},
2551− title = {PC Assembly Language},
2552− year = {2002},
2553− publisher = {http://www.drpaulcarter.com/},
2554− author = {Paul A. Carter}
2555−}
2556−
2557−@inproceedings{poly99,
2558− title = {Once Upon A Polymorphic Type},
2559− year = {1999},
2560− booktitle = {26th {ACM} {SIGPLAN}-SIGACT Symposium on Principles of Programming Languages},
2561− publisher = {{ACM}},
2562− author = {Keith Wansbrough and Simon {Peyton Jones}}
2563−}
2564−
2565−@misc{lazy_intro,
2566− title = {Compiling Lazy Functional Languages: An introduction},
2567− year = {1986},
2568− author = {Thomas Johnsson}
2569−}
2570−
2571−@inproceedings{unboxed-fp,
2572− month = {Sept},
2573− title = {Unboxed Values as First Class Citizens in a Non-Strict Functional Language},
2574− year = {1991},
2575− author = {Simon {Peyton Jones} and John Launchbury},
2576− booktitle = {Functional Programming Languages and Computer Architecture (FPCA'91)},
2577− crossref = {fplca91},
2578− pages = {636--666}
2579−}
2580−
2581−@inproceedings{abc-machine,
2582− author = {Sjaak Smetsers and Eric N{\"{o}}cker and John {van Groningen} and Rinus Plasmeijer},
2583− title = {Generating efficient code for lazy functional languages},
2584− booktitle = {Functional programming Languages and Computer Architecture},
2585− year = {1991},
2586− pages = {592--617},
2587− crossref = {fplca91}
2588−}
2589−
2590−@proceedings{fplca91,
2591− title = {Functional programming Languages and Computer Architecture},
2592− year = {1991},
2593− volume = {523},
2594− series = {LNCS},
2595− publisher = {Springer-Verlag},
2596− editor = {John Hughes}
2597−}
2598−
2599−
2600−
2601−@inproceedings{nbe,
2602− title = {An inverse of the evaluation functional for typed $\lambda$-calculus},
2603− year = {1991},
2604− booktitle = {Proc. 1991 {IEEE} Symp. on Logic in Comp. Sci.},
2605− pages = {203--211},
2606− editor = {R. Vemuri},
2607− author = {Ulrich Berger and Helmut Schwichtenberg}
2608−}
2609−
2610−@inproceedings{typed-closure,
2611− title = {Typed Closure Conversion},
2612− year = {1996},
2613− booktitle = {Symposium on Principles of Programming Languages},
2614− pages = {271--283},
2615− author = {Yasuhiko Minamide and J. Gregory Morrisett and Robert Harper}
2616−}
2617−
2618−@misc{ghc-commentary,
2619− howpublished = {http://www.cse.unsw.edu.au/~chak/haskell/ghc/comm/},
2620− title = {The Glasgow Haskell Compiler (GHC) Commentary},
2621− year = {2002},
2622− author = {Manuel M. T. Chakravarty and Sigbjorn Finne and Simon Marlow and Simon {Peyton Jones} and Julian Seward and Reuben Thomas},
2623− note = {Available from GHC CVS repository}
2624−}
2625−
2626−@inproceedings{lambdalift,
2627− month = {September},
2628− title = {Lambda Lifting: Transforming Programs to Recursive Equations},
2629− year = {1985},
2630− booktitle = {Functional Programming Languages and Computer Architecture},
2631− pages = {190--203},
2632− editor = {Jean-Pierre Jouannaud},
2633− publisher = {Springer-Verlag},
2634− author = {Thomas Johnsson}
2635−}
2636−
2637−@inproceedings{til,
2638− title = {TIL: A Type-Directed Optimizing Compiler for ML},
2639− year = {1996},
2640− booktitle = {Proc. {{ACM}} {{SIGPLAN}} '96 Conference on Programming Language Design and Implementation},
2641− pages = {181--192},
2642− author = {D. Tarditi and G. Morrisett and P. Cheng and C. Stone and R. Harper and P. Lee}
2643−}
2644−
2645−@phdthesis{shao94,
2646− school = {Princeton University},
2647− title = {Compiling Standard {ML} for Efficient Execution on Modern Machines},
2648− year = {1994},
2649− author = {Zhong Shao}
2650−}
2651−
2652−@inproceedings{gmachine,
2653− month = {September},
2654− title = {The {G-Machine}: A fast, graph-reduction evaluator},
2655− year = {1985},
2656− booktitle = {Functional Programming Languages and Computer Architecture},
2657− pages = {400--413},
2658− editor = {Jean-Pierre Jouannaud},
2659− publisher = {Springer-Verlag},
2660− author = {R.B. Kieburtz}
2661−}
2662−
2663−@inproceedings{strictness,
2664− month = {September},
2665− title = {Strictness Analysis - A practical approach},
2666− year = {1985},
2667− booktitle = {Functional Programming Languages and Computer Hardware},
2668− pages = {35--49},
2669− editor = {Jean-Pierre Jouannaud},
2670− publisher = {Springer-Verlag},
2671− author = {Chris Clack and Simon {Peyton Jones}}
2672−}
2673−
2674−@book{fl-impl,
2675− title = {Implementing Functional Languages - A Tutorial},
2676− year = {1992},
2677− publisher = {Prentice Hall International},
2678− author = {Simon {Peyton Jones} and David Lester}
2679−}
2680−
2681−@phdthesis{capretta-thesis,
2682− school = {Katholieke Universiteit Nijmegen},
2683− title = {Abstraction and Computation},
2684− year = {2002},
2685− author = {Venanzio Capretta}
2686−}
2687−
2688−@article{bird-pointer,
2689− journal = {Journal of Functional Programming},
2690− number = {3},
2691− month = {May},
2692− volume = {11},
2693− title = {Unfolding Pointer Algorithms},
2694− year = {2001},
2695− pages = {347--358},
2696− author = {Richard S. Bird}
2697−}
2698−
2699−@article{impl-tp,
2700− journal = {Journal of Functional Programming},
2701− number = {2},
2702− month = {March},
2703− volume = {9},
2704− title = {Implementing Theorem Provers in a Purely Functional Style},
2705− year = {1999},
2706− pages = {147--166},
2707− author = {Keith Hanna}
2708−}
2709−
2710−@article{shrink-lambda,
2711− journal = {Journal of Functional Programming},
2712− number = {5},
2713− month = {September},
2714− volume = {7},
2715− title = {Shrinking Lambda Expressions in Linear Time},
2716− year = {1997},
2717− pages = {515--540},
2718− author = {Andrew W. Appel and Trevor Jim}
2719−}
2720−
2721−@article{stack-tal,
2722− journal = {Journal of Functional Programming},
2723− number = {1},
2724− month = {January},
2725− volume = {12},
2726− title = {Stack-based Typed Assembly Language},
2727− year = {2002},
2728− pages = {43--88},
2729− author = {Greg Morrisset and Karl Crart and Neal Glew and David Walker}
2730−}
2731−
2732−@article{runtime-lamsig,
2733− journal = {Journal of Functional Programming},
2734− number = {2},
2735− month = {March},
2736− volume = {8},
2737− title = {Functional Runtime Systems within the lambda-sigma Calculus},
2738− year = {1998},
2739− pages = {131--176},
2740− author = {Th\'{e}r\`{e}se Hardin and Luc Maranget and Bruno Pagano}
2741−}
2742−
2743−@article{busylazy,
2744− journal = {Journal of Functional Programming},
2745− number = {6},
2746− month = {November},
2747− volume = {11},
2748− title = {How to look busy while being as lazy as ever: the Implementation of a lazy functional debugger},
2749− year = {2001},
2750− pages = {629--671},
2751− author = {Henrik Nilsson}
2752−}
2753−
2754−@article{lazyveager,
2755− journal = {Journal of Functional Programming},
2756− number = {5},
2757− month = {September},
2758− volume = {7},
2759− title = {More haste, less speed: lazy versus eager evaluation},
2760− year = {1997},
2761− pages = {541--547},
2762− author = {Richard Bird and Geraint Jones and Oege {de Moor}}
2763−}
2764−
2765−@article{jvm-fp,
2766− journal = {Journal of Functional Programming},
2767− number = {6},
2768− month = {November},
2769− volume = {9},
2770− title = {Compiling lazy functional programs for the Java Virtual Machine},
2771− year = {1999},
2772− pages = {579--603},
2773− author = {David Wakeling}
2774−}
2775−
2776−@book{isabelle,
2777− publisher = {Springer-Verlag},
2778− series = {LNCS},
2779− volume = {2283},
2780− month = {March},
2781− title = {Isabelle/HOL - A proof assistant for higher order logic},
2782− year = {2002},
2783− author = {Tobias Nipkow and Lawrence C. Paulson and Markus Wenzel}
2784−}
2785−
2786−@article{ghc-inliner,
2787− journal = {Journal of Functional Programming},
2788− number = {4},
2789− month = {September},
2790− volume = {12},
2791− title = {Secrets of the {Glasgow Haskell Compiler} inliner},
2792− year = {2002},
2793− pages = {393--434},
2794− author = {Simon {Peyton Jones} and Simon Marlow}
2795−}
2796−
2797−@article{dynamic-fp,
2798− journal = {Journal of Functional Programming},
2799− number = {1},
2800− month = {January},
2801− volume = {8},
2802− title = {The dynamic compiliation of lazy functional programs},
2803− year = {1998},
2804− pages = {61--81},
2805− author = {David Wakeling}
2806−}
2807−
2808−@misc{isabelle-ref,
2809− month = {March},
2810− title = {Isabelle Reference Manual},
2811− year = {2002},
2812− author = {Lawrence C. Paulson}
2813−}
2814−
2815−@article{debruijn-nested,
2816− journal = {Journal of Functional Programming},
2817− number = {1},
2818− month = {January},
2819− volume = {9},
2820− title = {de Bruijn notation as a nested datatype},
2821− year = {1999},
2822− pages = {77--91},
2823− author = {Richard S. Bird and Ross Paterson}
2824−}
2825−
2826−@article{perfect-trees,
2827− journal = {Journal of Functional Programming},
2828− number = {3},
2829− month = {May},
2830− volume = {10},
2831− title = {Perfect trees and bit-reversal permutations},
2832− year = {2000},
2833− pages = {305--317},
2834− author = {Ralf Hinze}
2835−}
2836−
2837−@phdthesis{paulin-extraction,
2838− school = {Paris 7},
2839− title = {Extraction de programmes dans le Calcul des Constructions},
2840− year = {1989},
2841− author = {Christine Paulin-Mohring}
2842−}
2843−
2844−@phdthesis{santos95,
2845− school = {University of Glasgow},
2846− title = {Compilation By Transformation In Non-Strict Functional Languages},
2847− year = {1995},
2848− author = {{Andr\'{e} Lu\'{i}s de Medeiros} Santos}
2849−}
2850−
2851−@book{cps,
2852− title = {Compiling With Continuations},
2853− year = {1992},
2854− publisher = {Cambridge University Press},
2855− author = {Andrew W. Appel}
2856−}
2857−
2858−@techreport{SKIM,
2859− number = {31},
2860− title = {The {SKIM} microprogrammer's guide},
2861− year = {1983},
2862− institution = {University of Cambridge},
2863− author = {W.R. Stoye}
2864−}
2865−
2866−@misc{NORMA,
2867− title = {An Overview of Burroughs {NORMA}},
2868− year = {1985},
2869− author = {H. Richards}
2870−}
2871−
2872−@book{ml,
2873− title = {The Definition of Standard ML --- Revised},
2874− year = {1997},
2875− publisher = {MIT Press},
2876− author = {Robin Milner and Mads Tofte and Robert Harper and David MacQueen}
2877−}
2878−
2879−@misc{ml71,
2880− title = {An intuitionistic theory of types},
2881− year = {1971},
2882− author = {Per Martin-L\"{o}f}
2883−}
2884−
2885−@phdthesis{girard-thesis,
2886− school = {Universit\'{e} Paris VII},
2887− title = {Interpr\'{e}tation fonctionelle et \'{e}limination des coupures de l'arithm\'{e}tique d'ordre sup\'{e}rieur},
2888− year = {1972},
2889− author = {Jean-Yves Girard}
2890−}
2891−
2892−@inproceedings{ml75,
2893− title = {An intuitionistic theory of types: predicative part},
2894− year = {1975},
2895− booktitle = {Logic Colloquium '73},
2896− editor = {H. Rose and J.C. Shepherdson},
2897− publisher = {North-Holland},
2898− author = {Per Martin-L\"{o}f}
2899−}
2900−
2901−@inproceedings{cpm90,
2902− title = {Inductively defined types},
2903− year = {1990},
2904− author = {Thierry Coquand and Christine Paulin-Mohring},
2905− series = {LNCS},
2906− volume = {417},
2907− publusher = {Springer-Verlag}
2908−}
2909−
2910−@phdthesis{fpcustom,
2911− month = {May},
2912− school = {Computer Lab, University of Cambridge},
2913− title = {The Implementation of Functional Languages using Custom Hardware},
2914− year = {1985},
2915− author = {W.R. Stoye}
2916−}
2917−
2918−@phdthesis{hughesthesis,
2919− month = {September},
2920− school = {Programming Research Group, Oxford},
2921− title = {The design and implementation of programming languages},
2922− year = {1984},
2923− author = {John Hughes}
2924−}
2925−
2926−@inproceedings{tim,
2927− volume = {274},
2928− title = {{TIM} -- A simple lazy abstract machine to execute supercombinators},
2929− year = {1987},
2930− booktitle = {Functional Programming Languages and Computer Architecture},
2931− publisher = {Springer-Verlag},
2932− author = {John Fairbairn and Stuart Wray},
2933− pages = {34--45},
2934− series = {LNCS}
2935−}
2936−
2937−@techreport{abc,
2938− title = {The {ABC} machine -- A Sequential Stack-based Abstract Machine For Graph Rewriting},
2939− year = {1990},
2940− institution = {University of Nijmegen},
2941− author = {P.W.M. Koopman and M.C.J.D. van {Eekelen} and E.G.J.M.H. Ncker and J.E.W. Smetsers and M.J. Plasmeijer}
2942−}
2943−
2944−@techreport{implicit,
2945− title = {On Implicit Arguments},
2946− year = {1994},
2947− institution = {Faculty of Science, University of Tokyo},
2948− author = {Masami Hagiya and Yozo Toda}
2949−}
2950−
2951−@book{semantics,
2952− title = {Denotational Semantics},
2953− year = {1986},
2954− publisher = {Wm. C. Brown},
2955− author = {David A. Schmidt}
2956−}
2957−
2958−@inproceedings{lazyml,
2959− month = {August},
2960− title = {A compiler for {Lazy} {ML}},
2961− year = {1984},
2962− booktitle = {Proceedings of the {{ACM}} Symposium on Lisp and Functional Programming},
2963− pages = {218--227},
2964− author = {Lennart Augustsson}
2965−}
2966−
2967−@inproceedings{nu-g,
2968− title = {Parallel graph reduction with the $\langle\nu,G\rangle$-machine},
2969− year = {1989},
2970− booktitle = {Functional Programming Languages and Computer Architecture},
2971− publisher = {{ACM} Press},
2972− author = {Lennart Augustsson and Thomas Johnsson}
2973−}
2974−
2975−@book{k&r,
2976− title = {The C programming language},
2977− year = {1988},
2978− publisher = {Prentice-Hall},
2979− author = {Brian W. Kernighan and Dennis M. Ritchie}
2980−}
2981−
2982−@misc{c--garbage,
2983− title = {C--: a portable assembly language that supports garbage collection},
2984− year = {1999},
2985− author = {Simon {Peyton Jones} and Norman Ramsey and Fermin Reig},
2986− note = {Invited talk at PPDP'99}
2987−}
2988−
2989−@misc{epigram,
2990− howpublished = {http://www.dur.ac.uk/CARG/epigram.html},
2991− title = {Project Proposal: {Epigram}: Innovative Programming via Inductive Families},
2992− year = {2002},
2993− author = {Zhaohui Luo and James McKinna and Paul Callaghan and Conor McBride}
2994−}
2995−
2996−@misc{ghc-rewrite,
2997− title = {Playing by the Rules: Rewriting as a practical optimisation technique in {GHC}},
2998− year = {2001},
2999− author = {Simon {Peyton Jones} and Andrew Tolmach and Tony Hoare}
3000−}
3001−
3002−@UNPUBLISHED{implicit-pollack,
3003− AUTHOR = {Robert Pollack},
3004− TITLE = {Implicit Syntax},
3005− NOTE = {Informal Proceedings of First Workshop on
3006− Logical Frameworks, Antibes},
3007− YEAR = {1990},
3008− MONTH = MAY
3009−}
3010−
3011−
3012−@article{transform-haskell,
3013− journal = {Science of Computer Programming},
3014− volume = {32},
3015− title = {A transformation-based optimiser for {Haskell}},
3016− year = {1998},
3017− pages = {3--47},
3018− author = {Simon {Peyton Jones} and Andr\'{e} L. M. Santos}
3019−}
3020−
3021−@inproceedings{knuth-bendix,
3022− title = {Simple Word Problems in Universal Algebras},
3023− year = {1970},
3024− booktitle = {Computational Problems in Abstract Algebra},
3025− pages = {263--298},
3026− editor = {John Leech},
3027− publisher = {Pergamon Press},
3028− author = {Donald E. Knuth and Peter B. Bendix}
3029−}
3030−
3031−@inproceedings{phantomfun,
3032− title = {Fun With Phantom Types},
3033− author = {Ralf Hinze},
3034− pages = {245--262},
3035− year = {2003},
3036− crossref = {funprogramming},
3037− booktitle = {The Fun Of Programming},
3038− publisher = {Palgrave}
3039−}
3040−
3041−@book{funprogramming,
3042− month = {March},
3043− title = {The Fun Of Programming},
3044− year = {2003},
3045− editor = {Jeremy Gibbons and Oege {de Moor}},
3046− publisher = {Palgrave},
3047− series = {Cornerstones of Computing}
3048−}
3049−
3050−@inproceedings{anderson-proof,
3051− title = {Representing Proof Transformations For Program Optimization},
3052− year = {1994},
3053− booktitle = {International Conference On Automated Deduction},
3054− publisher = {Springer Verlag},
3055− author = {Penny Anderson}
3056−}
3057−
3058−@phdthesis{daria-thesis,
3059− month = {April},
3060− school = {Institute of Informatics, Warsaw University},
3061− title = {Termination of Rewriting in the Calculus of Constructions},
3062− year = {2003},
3063− author = {Daria Walukiewicz-Chrzaszcz}
3064−}
3065−
3066−@inproceedings{change-data,
3067− title = {Changing Data Structures In Type Theory: A Study Of Natural Numbers},
3068− year = {2001},
3069− booktitle = {Types For Proofs And Programs 2000},
3070− pages = {181--196},
3071− editor = {Paul Callaghan and Zhaohui Luo and James McKinna and Robert Pollack},
3072− publisher = {Springer},
3073− author = {Nicolas Magaud and Yves Bertot}
3074−}
3075−
3076−@phdthesis{nico-thesis,
3077− title = {Changement de Representation des donn\'{e}es dans le Calcul de Constructions},
3078− author = {Nicolas Magaud},
3079− year = {2003},
3080− month = {October},
3081− school = {Universit\'{e} de Nice - Sophia Antipolis}
3082−}
3083−
3084−
3085−@book{patterns,
3086− title = {Design Patterns},
3087− year = {1995},
3088− publisher = {Addison Wesley},
3089− author = {Erich Gamma and Richard Helm and Ralph Johnson and John Vlissides}
3090−}
3091−
3092−@misc{ghchugs,
3093− month = {August},
3094− title = {The New {GHC}/{Hugs} Runtime System},
3095− year = {1998},
3096− author = {Simon Marlow and Simon {Peyton Jones}}
3097−}
3098−
3099−@misc{stgrevised,
3100− month = {February},
3101− title = {The {STG} runtime system (revised)},
3102− year = {1999},
3103− author = {Simon {Peyton Jones} and Simon Marlow and Alastair Reid},
3104− howpublished = {Available from \verb+http://www.haskell.org/ghc/documentation.html+}
3105−}
3106−
3107−@inproceedings{optimistic,
3108− month = {March},
3109− title = {Optimistic Evaluation --- an adaptive evaluation strategy for non-strict programs},
3110− year = {2003},
3111− author = {Robert Ennals and Simon {Peyton Jones}},
3112− booktitle = {International Conference on Functional Programming},
3113− pages = {287--298}
3114−}
3115−
3116−@phdthesis{ennals-thesis,
3117− title = {Adaptive Evaluation of Non-Strict Programs},
3118− author = {Robert Ennals},
3119− year = {2003},
3120− month = {December},
3121− school = {King's College, University of Cambridge}
3122−}
3123−
3124−@article{garbage,
3125− journal = {{ACM} Computing Surveys},
3126− number = {3},
3127− volume = {13},
3128− title = {Garbage Collection of Linked Data Structures},
3129− year = {1981},
3130− pages = {341--367},
3131− author = {Jacques Cohen}
3132−}
3133−
3134−@article{baker-gc,
3135− journal = {Communications of the {ACM}},
3136− number = {4},
3137− month = {April},
3138− volume = {21},
3139− title = {List Processing In Real Time On A Serial Computer},
3140− year = {1978},
3141− pages = {280--294},
3142− author = {Henry G. {Baker Jr}}
3143−}
3144−
3145−@misc{bc-rec,
3146− month = {February},
3147− title = {Modelling General Recursion in Type Theory},
3148− year = {2003},
3149− note = {Under consideration for publication in Math. Struct. in Comp. Science. Draft, DCS, CTH --- INRIA, Sophia Antipolis, France},
3150− author = {Ana Bove and Venanzio Capretta}
3151−}
3152−
3153−@misc{global-tag,
3154− title = {Global Tagging Optimization by Type Inference},
3155− year = {1992},
3156− author = {Fritz Henglein}
3157−}
3158−
3159−@book{esr,
3160− month = {October},
3161− title = {The Cathedral And The Bazaar},
3162− year = {1999},
3163− publisher = {O'Reilly},
3164− author = {Eric Raymond}
3165−}
3166−
3167−@book{manmonth,
3168− title = {The Mythical Man-month: Essays on Software Engineering},
3169− year = {1975},
3170− publisher = {Addison Wesley},
3171− author = {Frederick P. Brooks}
3172−}
3173−
3174−@inproceedings{evalpush,
3175− title = {How to make a fast curry: push/enter vs eval/apply},
3176− year = {2004},
3177− author = {Simon Marlow and Simon {Peyton Jones}},
3178− booktitle = {International Conference on Functional Programming, Snowbird},
3179− pages = {4--15}
3180−}
3181−
3182−@phdthesis{boquist-thesis,
3183− month = {April},
3184− school = {Chalmers University of Technology},
3185− title = {Code Optimisation Techniques for Lazy Functional Languages},
3186− year = {1999},
3187− author = {Urban Boquist}
3188−}
3189−
3190−@book{formal-spec,
3191− title = {Formal Specification Of Programming Languages},
3192− year = {1981},
3193− publisher = {Prentice-Hall},
3194− author = {Frank G. Pagan}
3195−}
3196−
3197−@inproceedings{elim-motive,
3198− title = {Elimination With A Motive},
3199− year = {2000},
3200− booktitle = {Types for Proofs and Programs},
3201− pages = {197--216},
3202− editor = {Paul Callaghan and Zhaohui Luo and James McKinna and Robert Pollack},
3203− publisher = {Springer},
3204− author = {Conor McBride}
3205−}
3206−
3207−@article{telescope,
3208− journal = {Information and Computation},
3209− number = {2},
3210− month = {April},
3211− volume = {91},
3212− title = {Telescoping Mappings in Typed Lambda Calculus},
3213− year = {1991},
3214− pages = {189--204},
3215− author = {N.G. de Bruijn}
3216−}
3217−
3218−@misc{typeintype,
3219− title = {Typechecking is undecidable when 'type' is a type},
3220− year = {1989},
3221− author = {Mark B. Reinhold}
3222−}
3223−
3224−@misc{core,
3225− month = {September},
3226− title = {An External Representation for the {GHC} Core Language},
3227− year = {2001},
3228− author = {Andrew Tolmach and {The GHC Team}}
3229−}
3230−
3231−@article{deforestation,
3232− journal = {Theoretical Computer Science},
3233− volume = {73},
3234− title = {Deforestation: Transforming programs to eliminate trees},
3235− year = {1990},
3236− pages = {231--248},
3237− author = {Philip Wadler}
3238−}
3239−
3240−@misc{hep,
3241− month = {July},
3242− title = {Architecture of the {Haskell} Execution Platform},
3243− year = {1999},
3244− author = {Julian Seward and Simon Marlow and Andy Gill and Sigbjorn Finne and Simon {Peyton Jones} },
3245− note = {Version 6},
3246− howpublished = {Available from \verb+http://www.haskell.org/ghc/documentation.html+}
3247−}
3248−
3249−@mastersthesis{wahlstedt-thesis,
3250− month = {October},
3251− school = {Chalmers University Of Technology},
3252− title = {Detecting Termination Using Size Change In Parameter Values},
3253− year = {2000},
3254− author = {David Wahlstedt}
3255−}
3256−
3257−@inproceedings{size-change,
3258− title = {The size-change principle for program termination},
3259− year = {2001},
3260− booktitle = {Proceedings of the 28th Annual {ACM} {SIGPLAN}-SIGACT Symposium on Principles of Programming Languages},
3261− author = {Chin Soon Lee and Neil D. Jones and Amir Ben-Amram. }
3262−}
3263−
3264−@article{ski-turner,
3265− journal = {Software -- Practice and Experience},
3266− volume = {9},
3267− title = {A new implementation technique for applicative languages},
3268− year = {1979},
3269− pages = {31--49},
3270− author = {David Turner}
3271−}
3272−
3273−@inproceedings{turner-strong,
3274− number = {1022},
3275− title = {Elementary Strong Functional Programming},
3276− year = {1996},
3277− booktitle = {First International Symposium on Functional Programming Languages in Education, Nijmegen, Netherlands, December 1995.},
3278− pages = {1--13},
3279− publisher = {Springer},
3280− author = {David Turner},
3281− series = {LNCS}
3282−}
3283−
3284−@misc{clean,
3285− title = {The {Concurrent CLEAN} Language Report (draft)},
3286− year = {2003},
3287− author = {Rinus Plasmeijer and Marko van Eekelen},
3288− howpublished = {Available from \verb+http://www.cs.kun.nl/~clean/+}
3289−}
3290−
3291−@article{burstall-struct,
3292− journal = {Computer Journal},
3293− number = {1},
3294− volume = {12},
3295− title = {Proving Properties of Programs By Structural Induction},
3296− year = {1969},
3297− pages = {41--48},
3298− author = {Rod Burstall}
3299−}
3300−
3301−@incollection{ barendregt-types,
3302− author = "Henk Barendregt",
3303− title = "Lambda Calculi with Types",
3304− booktitle = "Handbook of Logic in Computer Science, Volumes 1 (Background: Mathematical Structures) and 2 (Background: Computational Structures), Abramsky \& Gabbay \& Maibaum (Eds.)",
3305− publisher = "Clarendon",
3306− volume = "2",
3307− year = "1992",
3308− url = "citeseer.nj.nec.com/barendregt92lambda.html" }
3309−
3310−@book{curry-feys,
3311− title = {Combinatory Logic, volume 1},
3312− year = {1958},
3313− publisher = {North Holland},
3314− author = {Haskell B. Curry and Robert Feys}
3315−}
3316−
3317−@phdthesis{bove-thesis,
3318− month = {November},
3319− school = {Chalmers University of Technology},
3320− title = {General Recursion in Type Theory},
3321− year = {2002},
3322− author = {Ana Bove}
3323−}
3324−
3325−@inbook{ml-cm,
3326− title = {Constructive Mathematics and Computer Programming},
3327− year = {1985},
3328− booktitle = {Mathematical Logic and Programming Languages},
3329− publisher = {Prentice Hall},
3330− author = {Per Martin-L\"{o}f}
3331−}
3332−
3333−@inproceedings{howard,
3334− title = {The formulae-as-types notion of construction},
3335− year = {1980},
3336− booktitle = {To H.B.Curry: Essays on combinatory logic, lambda calculus and formalism},
3337− editor = {Jonathan P. Seldin and J. Roger Hindley},
3338− publisher = {Academic Press},
3339− author = {William A. Howard},
3340− note = {A reprint of an unpublished manuscript from 1969}
3341−}
3342−
3343−@inproceedings{talx86,
3344− title = {TALx86: A Realistic Typed Assembly Language},
3345− year = {1999},
3346− booktitle = {{ACM} {SIGPLAN} Workshop on Compiler Support for System Software},
3347− pages = {25--35},
3348− author = {Greg Morrisett and Karl Crary and Neal Glew and Dan Grossman and Richard Samuels and Frederick Smith and David Walker and Stephanie Weirich and Steve Zdancewic}
3349−}
3350−
3351−@inproceedings{bove-capretta,
3352− volume = {2152},
3353− title = {Nested General Recursion and Partiality in Type Theory},
3354− year = {2001},
3355− booktitle = {Theorem Proving in Higher Order Logics, 14th International Conference, TPHOLS 2001},
3356− pages = {121--135},
3357− editor = {Richard J. Boulton and Paul B. Jackson},
3358− publisher = {Springer-Verlag},
3359− author = {Ana Bove and Venanzio Capretta},
3360− series = {LNCS}
3361−}
3362−
3363−@misc{lvm,
3364− month = {November},
3365− title = {LVM, the lazy virtual machine},
3366− year = {2002},
3367− author = {Daan Leijen}
3368−}
3369−
3370−@misc{ocaml,
3371− howpublished = {\verb+http://caml.inria.fr/ocaml/htmlman/+},
3372− month = {August},
3373− title = {The {Objective Caml} system release 3.06},
3374− year = {2002},
3375− author = {Xavier Leroy}
3376−}
3377−
3378−@misc{lambdagoto,
3379− title = {Lambda : The Ultimate Goto},
3380− year = {1977},
3381− author = {Guy L. {Steele Jr}},
3382− note = {MIT AI Memo 443}
3383−}
3384−
3385−@inproceedings{ liu-tail,
3386− author = "Yanhong A. Liu and Scott D. Stoller",
3387− title = "From Recursion to Iteration: What are the Optimizations?",
3388− booktitle = "Partial Evaluation and Semantic-Based Program Manipulation",
3389− pages = "73-82",
3390− year = "2000",
3391− url = "citeseer.nj.nec.com/liu00from.html" }
3392−
3393−@inproceedings{aczel77,
3394− title = {An Introduction To Inductive Definitions},
3395− year = {1977},
3396− booktitle = {Handbook of Mathematical Logic},
3397− editor = {J. Barwise},
3398− publisher = {North Holland},
3399− author = {Peter Aczel}
3400−}
3401−
3402−@inproceedings{inductive-plastic,
3403− volume = {1956},
3404− title = {Implementation Techniques for Inductive Types in {Plastic}},
3405− year = {1999},
3406− booktitle = {Types for Proofs and Programs},
3407− pages = {94--113},
3408− editor = {Thierry Coquand and Peter Dybjer and Bengt Nordstr\"{o}m and Jan Smith},
3409− publisher = {Springer-Verlag},
3410− author = {Paul Callaghan and Zhaohui Luo},
3411− series = {LNCS}
3412−}
3413−
3414−@misc{graham,
3415− howpublished = {Available from \verb+http://www.paulgraham.com/+},
3416− month = {April},
3417− title = {The Hundred Year Language},
3418− year = {2003},
3419− author = {Paul Graham},
3420− note = {Keynote address at PyCon 2003}
3421−}
3422−
3423−@inproceedings{gimenez98,
3424− volume = {1443},
3425− title = {Structural Recursive Definitions in Type Theory},
3426− year = {1998},
3427− booktitle = {Proceedings of ICALP '98},
3428− publisher = {Springer-Verlag},
3429− author = {Eduardo Gim\'{e}nez},
3430− series = {LNCS}
3431−}
3432−
3433−@article{quicksort,
3434− journal = {Computer Journal},
3435− number = {1},
3436− volume = {5},
3437− title = {Quicksort},
3438− year = {1962},
3439− pages = {10--15},
3440− author = {C.A.R. Hoare}
3441−}
3442−
3443−@phdthesis{goguen-thesis,
3444− school = {University of Edinburgh},
3445− title = {A Typed Operational Semantics for Type Theory},
3446− year = {1994},
3447− author = {Healfdene Goguen}
3448−}
3449−
3450−@article{ph-universes,
3451− journal = {Theoretical Computer Science},
3452− number = {1},
3453− volume = {89},
3454− title = {Type Checking With Universes},
3455− year = {1991},
3456− pages = {107--136},
3457− author = {Robert Harper and Randy Pollack}
3458−}
3459−
3460−@inproceedings{pm-compile,
3461− month = {September},
3462− title = {Compiling Pattern Matching},
3463− year = {1985},
3464− booktitle = {Functional Programming Languages and Computer Architecture},
3465− pages = {368--381},
3466− editor = {Jean-Pierre Jouannaud},
3467− publisher = {Springer-Verlag},
3468− author = {Lennart Augustsson}
3469−}
3470−
3471−@phdthesis{lena-thesis,
3472− school = {Chalmers University of Technology, G\"{o}teborg},
3473− title = {The implementation of {ALF} -- A Proof Editor based on {Martin-L\"{o}f}'s Monomorphic Type Theory with Explicit Substitutions},
3474− year = {1994},
3475− author = {Lena Magnusson}
3476−}
3477−
3478−@article{view-left,
3479− journal = {Journal of Functional Programming},
3480− number = {1},
3481− volume = {14},
3482− title = {The View From The Left},
3483− year = {2004},
3484− author = {Conor McBride and James McKinna},
3485− pages = {69--111}
3486−}
3487−
3488−@inproceedings{not-a-number,
3489− author = {Conor McBride and James McKinna},
3490− title = {I am not a number, {I} am a free variable},
3491− year = {2004},
3492− booktitle = {Proceedings of the {ACM} {SIGPLAN} Haskell Workshop}
3493−}
3494−
3495−
3496−@misc{profiling,
3497− title = {Time and Space Profiling for Non-Strict, Higher Order Functional Languages},
3498− year = {1995},
3499− author = {Patrick M. Sansom and Simon {Peyton Jones}}
3500−}
3501−
3502−@inbook{pattern-matching,
3503− title = {The Implementation of Functional Programming Languages},
3504− year = {1987},
3505− booktitle = {The Implementation of Functional Programming Languages},
3506− pages = {78--103},
3507− editor = {Simon {Peyton Jones}},
3508− chapter = {5},
3509− publisher = {Prentice Hall},
3510− author = {Philip Wadler},
3511− crossref = {pj-imp}
3512−}
3513−
3514−@article{pe-problems,
3515− author = {Jones, N. D.},
3516− title = {Challenging problems in partial evaluation and mixed computation},
3517− journal = {New Gen. Comput.},
3518− volume = {6},
3519− number = {2-3},
3520− year = {1988},
3521− issn = {0288-3635},
3522− pages = {291--302},
3523− doi = {http://dx.doi.org/10.1007/BF03037143},
3524− publisher = {Ohmsha},
3525− address = {Tokyo, Japan, Japan},
3526− }
3527−
3528−@inproceedings{tag-elim,
3529− title = {Tag Elimination -- or -- Type Specialisation is a Type Indexed Effect},
3530− year = {2000},
3531− booktitle = {Subtyping and Dependent Types in Programming, APPSEM Workshop},
3532− author = {Walid Taha and Henning Makholm}
3533−}
3534−
3535−@inproceedings{extraction-coq,
3536− title = {A New Extraction for {Coq}},
3537− year = {2002},
3538− booktitle = {Types for proofs and programs},
3539− editor = {Herman Geuvers and Freek Wiedijk},
3540− publisher = {Springer},
3541− author = {Pierre Letouzey},
3542− series = {LNCS}
3543−}
3544−
3545−@phdthesis{mcbride-snr-thesis,
3546− school = {Queen's University of Belfast},
3547− title = {Computer Aided Manipulation of Symbols},
3548− year = {1970},
3549− author = {Fred McBride}
3550−}
3551−
3552−@article{ho-strictness,
3553− journal = {Science of Computer Programming},
3554− volume = {7},
3555− title = {Strictness analysis for higher-order functions},
3556− year = {1986},
3557− pages = {249--278},
3558− author = { Geoffrey L. Burn and Chris Hankin and Samson Abramsky}
3559−}
3560−
3561−@phdthesis{mycroft-thesis,
3562− school = {Dept Computer Science, University of Edinburgh},
3563− title = {Abstract interpretation and optimising transformations for applicative programs},
3564− year = {1981},
3565− author = {A. Mycroft}
3566−}
3567−
3568−@inproceedings{bc-nested,
3569− month = {September},
3570− volume = {2152},
3571− title = {Nested General Recursion and Partiality in Type Theory},
3572− year = {2001},
3573− booktitle = {Theorem Proving In Higher Order Logics: 14th International Conferences, TPHOLS 2001},
3574− pages = {121--135},
3575− publisher = {Springer--Verlag},
3576− author = {Ana Bove and Venanzio Capretta},
3577− series = {LNCS}
3578−}
3579−
3580−@techreport{bove-mutual,
3581− month = {May},
3582− title = {Mutual General Recursion in Type Theory},
3583− year = {2002},
3584− institution = {Department of Computing Science, Chalmers University of Technology},
3585− author = {Ana Bove}
3586−}
3587−
3588−@article{berardi-pruning,
3589− journal = {Journal of Logic and Computation},
3590− number = {5},
3591− volume = {6},
3592− title = {Pruning Simply Typed Lambda Terms},
3593− year = {1996},
3594− pages = {663--681},
3595− author = {Stefano Berardi}
3596−}
3597−
3598−@article{milner-tc,
3599− journal = {Journal of Computer and System Science},
3600− volume = {17},
3601− title = {A Theory of Type Polymorphism in Programming},
3602− year = {1978},
3603− pages = {348--75},
3604− author = {R. Milner}
3605−}
3606−
3607−@inproceedings{extt,
3608− title = {Inductive Families Need Not Store Their Indices},
3609− year = {2004},
3610− booktitle = {Types for Proofs and Programs 2003},
3611− author = {Edwin Brady and Conor McBride and James McKinna},
3612− editor = {Stefano Berardi and Mario Coppo and Ferruccio Damiani},
3613− series = {Lecture Notes in Computer Science},
3614− publisher = {Springer},
3615− volume = {3085},
3616− pages = {115--129}
3617−}
3618−
3619−@book{luo94,
3620− title = {Computation and Reasoning -- A Type Theory for Computer Science},
3621− year = {1994},
3622− publisher = {OUP},
3623− author = {Zhaohui Luo},
3624− series = {Intl. Series of Monographs on Comp. Sci.}
3625−}
3626−
3627−@article{backus78,
3628− journal = {Communications of the {ACM}},
3629− month = {August},
3630− volume = {21},
3631− title = {Can Programming Be Liberated From the {Von Neumann} Style?},
3632− year = {1978},
3633− pages = {280--294},
3634− author = {John Backus}
3635−}
3636−
3637−@misc{henk,
3638− month = {May},
3639− title = {Henk: A Typed Intermediate Language},
3640− year = {1997},
3641− author = {Simon {Peyton Jones} and Erik Meijer}
3642−}
3643−
3644−@article{thunks,
3645− journal = {Journal of Functional Programming},
3646− number = {3},
3647− month = {May},
3648− volume = {7},
3649− title = {Thunks and the $\lambda$-calculus},
3650− year = {1997},
3651− pages = {303--319},
3652− author = {John Hatcliff and Olivier Danvy}
3653−}
3654−
3655−@inproceedings{grin-project,
3656− author = "Urban Boquist and Thomas Johnsson",
3657− title = "The {GRIN} Project: A Highly Optimising Back End for Lazy Functional Languages",
3658− booktitle = "Implementation of Functional Languages",
3659− pages = "58--84",
3660− year = "1996",
3661− url = "citeseer.ist.psu.edu/boquist96grin.html" }
3662−
3663−@misc{boehm-gc,
3664− nothowpublished = {\url{http://www.hpl.hp.com/personal/Hans_Boehm/gc/}},
3665− title = {A garbage collector for {C} and {C++}},
3666− year = {2001},
3667− author = {Hans-J. Boehm and Alan J. Demers and {Xerox Corporation Silicon Graphic} and {Hewlett-Packard Company}}
3668−}
3669−
3670−@misc{art-interpreter,
3671− month = {May},
3672− title = {The Art of the Interpreter or, the Modularity Complex (Parts Zero, One, and Two)},
3673− year = {1978},
3674− author = {Guy Lewis {Steele, Jr.} and Gerald Jay Sussman},
3675− note = {MIT AI Lab. AI Lab Memo AIM-453}
3676−}
3677−
3678−@inproceedings{gimenez,
3679− title = {Codifying Guarded Definitions With Recursive Schemes},
3680− year = {1994},
3681− booktitle = {Proceedings of TYPES 1994},
3682− pages = {39--59},
3683− author = {Eduardo Gim\'{e}nez}
3684−}
3685−
3686−@manual{ghc-manual,
3687− title = {The Glasgow Haskell Compiler User's Guide, Version 6.0},
3688− year = {2003},
3689− author = {The {GHC Team}}
3690−}
3691−
3692−@article{rbtree,
3693− journal = {Journal of Functional Programming},
3694− number = {4},
3695− month = {May},
3696− volume = {9},
3697− title = {Red-Black Trees In A Functional Setting},
3698− year = {1999},
3699− pages = {471--477},
3700− author = {Chris Okasaki}
3701−}
3702−
3703−@inproceedings{dt-data,
3704−author = "Hongwei Xi",
3705−title = {{Dependently Typed Data Structures}},
3706−booktitle = "Proceedings of Workshop of Algorithmic Aspects of Advanced Programming Languages (WAAAPL '99)",
3707−year = 1999,
3708−month = "September",
3709−pages = "17--32",
3710−address = "Paris",
3711−}
3712−
3713−@misc{krivine,
3714− title = {On the Correctness and Efficiency of the {Krivine} Machine},
3715− year = {2003},
3716− month = {October},
3717− author = {Mitchell Wand and Daniel P. Friedman},
3718− howpublished = {Submitted for publication}
3719− }
3720−
3721−@inproceedings{nbe-filinski,
3722− title = {Normalization by Evaluation for the Computational Lambda-Calculus},
3723− year = {2001},
3724− month = {May},
3725− booktitle = {Typed Lambda Calculi and Applications: 5th International Conference, TLCA 2001},
3726− author = {Andrzej Filinski},
3727− pages = {151--165},
3728− publisher = {Springer-Verlag},
3729− series = {LNCS},
3730− volume = {2044}
3731−}
3732−
3733−@inproceedings{filinski-nbesem,
3734− title = {A semantic account of type-directed partial evaluation},
3735− year = {1999},
3736− author = {Andrzej Filinski},
3737− editor = {G. Nadathur},
3738− booktitle = {International Conference on Principles and Practice of Declarative Programming},
3739− volume = {1702},
3740− series = {LNCS},
3741− pages = {378--395},
3742− publisher = {Springer-Verlag}
3743−}
3744−
3745−@article{secd,
3746− title = {The mechanical evaluation of expressions},
3747− author = {P.J. Landin},
3748− year = {1964},
3749− journal = {Computer Journal},
3750− volume = {6},
3751− pages = {308--320}
3752−}
3753−
3754−@misc{lispkit,
3755− title = {The {LispKit} Manual},
3756− author = {Peter Henderson and Geraint Jones and Simon Jones},
3757− year = {1982},
3758− howpublished = {Oxford University Computing Laboratory}
3759−}
3760−
3761−@inproceedings{wells-undecidable,
3762− title = {Typability and Type Checking in the Second-order $\lambda$-calculus are equivalent and undecidable},
3763− author = {J. Wells},
3764− year = {1994},
3765− month = {July},
3766− booktitle = {Proc. 9th Ann. {IEEE} Symp. Logic Comput. Sci.}
3767−}
3768−
3769−@misc{patguards,
3770− title = {Pattern Guards and Transformational Patterns},
3771− author = {Martin Erwig and Simon {Peyton Jones}},
3772− year = {2000},
3773− howpublished = {Haskell Workshop}
3774−}
3775−
3776−@misc{alfa-manual,
3777− title = {Alfa Users' Guide},
3778− author = {Thomas Hallgren},
3779− year = {2001},
3780− howpublished = {Available from \verb+http://www.cs.chalmers.se/~hallgren/Alfa/+}
3781−}
3782−
3783−@inproceedings{nofib,
3784− title = {The nofib Benchmark Suite of {Haskell} Programs},
3785− author = {Will Partain},
3786− year = {1992},
3787− booktitle = {Functional Programming},
3788− editor = {J. Launchbury and P.L. Sansom},
3789− series = {Workshops in Computing},
3790− publisher = {Springer Verlag}
3791−}
3792−
3793−@article{shape,
3794− title = {Shape in Computing},
3795− author = {Barry Jay},
3796− journal = "{{ACM}} Computing Surveys",
3797− year = "1996",
3798− volume = "28",
3799− number = "2",
3800− pages = "355--357",
3801−}
3802−
3803−@misc{ffi,
3804− title = {The {Haskell 98} Foreign Function Interface 1.0: An Addendum to the {Haskell 98} Report},
3805− editor = {Manuel Chakravarty},
3806− key = {FFI},
3807− year = {2002},
3808− month = {December},
3809− howpublished = {Available from \verb+http://www.haskell.org/+}
3810−}
3811−
3812−@misc{perlxs,
3813− title = {Perl {XS} Reference Manual},
3814− author = {Dean Roehrich and {The Perl Porters}},
3815− year = {1996},
3816− howpublished = {\verb+http://www.perldoc.com/perl5.6/pod/perlxs.html+}
3817−}
3818−
3819−@misc{swig,
3820− title = {{SWIG} : An Easy to Use Tool for Integrating Scripting Languages with {C} and {C++}},
3821− author = {David M. Beazley},
3822− year = {1996},
3823− howpublished = {\verb+http://www.swig.org/papers/Tcl96/tcl96.html+}
3824−}
3825−
3826−@inproceedings{types-prog,
3827− title = {Type Systems for Programming Languages},
3828− booktitle = {Handbook of Theoretical Computer Science},
3829− author = {John C. Mitchell},
3830− pages = {365--458},
3831− year = {1990},
3832− crossref = {htcs}
3833−}
3834−
3835−@book{htcs,
3836− title = {Handbook of Theoretical Computer Science},
3837− editor = {J. van Leeuwen},
3838− publisher = {Elsevier Science},
3839− year = {1990}
3840−}
3841−
3842−@misc{r5rs,
3843− title = {Revised$^5$ Report on the Algorithmic Language Scheme},
3844− author = {Richard Kelsey and William Clinger and Jonathan Rees},
3845− year = {1998},
3846− month = {February},
3847− howpublished = {Available from \verb+http://www.schemers.org/+}
3848− }
3849−
3850−@misc{gmail-outage,
3851− title = {Update on today's {Gmail} Outage},
3852− author = {{Official Gmail Blog}},
3853− howpublished = {\url{http://gmailblog.blogspot.com/2009/02/update-on-todays-gmail-outage.html}},
3854− note = {Retrieved 26th February 2009},
3855− year = 2009
3856−}