-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsugar.lp
284 lines (232 loc) · 6.85 KB
/
sugar.lp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
-- ------------------------------------------
-- DataTypes
-- ------------------------------------------
-- Works like Haskells Maybe
datatype Cake a := Sweet a | Lie
-- either the cake is a Sweet or
-- the cake is a lie
function getCake : (Cake a) -> b
getCake (Sweet x) := x
getCake Lie := undefined
datatype Boolean := True | False
-- ------------------------------------------
-- misc functions
function id : a -> a
id x := x
-- ------------------------------------------
-- Mathematical functions
-- ------------------------------------------
-- The factorial function
function fac : a -> b
fac 0 := 1
fac x := x * (fac (x-1))
-- Calculates the n:th Fibonacci number
function fib : Int -> Int
fib 0 := 0
fib 1 := 1
fib n := fib (n-2) +
fib (n-1)
-- Calculates the absolute value
function abs : Int -> Int
abs x
:= -x when x < 0
:= x
-- Returns the "sign" for integers (1 for
-- numbers >= 0 and -1 for numbers < 0)
function sign : Int -> Int
sign x
:= -1 when x < 0
:= 1
-- Integer division
function div : Int -> Int -> Int
div _ 0 := undefined
div 0 _ := 0
div x y
:= div (-x) (-y) when y < 0
:= -1 + div (x+y) y when x < 0
:= 1 + div (x-y) y when x > y
:= 1 when x == y
:= 0
-- Modulus
function mod : Int -> Int -> Int
mod x y := x - y * div x y
-- Returns the successor of an integer
function succ : Int -> Int
succ x := x + 1
-- Returns the predecessor of an integer
function pred : Int -> Int
pred x := x - 1
-- Calculates the greatest common divisor
-- of the two arguments
function gcd : Int -> Int -> Int
gcd x 0 := abs x
gcd x y := gcd y (mod x y)
-- Calculates the least common multiple
-- of the two arguments
function lcm : Int -> Int -> Int
lcm 0 0 := 0
lcm x y := div (abs (x*y)) (gcd x y)
-- ------------------------------------------
-- Logical functions
-- ------------------------------------------
-- Returns true if argument is odd
function isOdd : Int -> Boolean
isOdd x := mod x 2 == 1
-- Returns true if argument is even
function isEven : Int -> Boolean
isEven x := mod x 2 == 0
-- Checks if a list of Booleans only
-- contains Trues
function and : [Boolean] -> Boolean
and xs := foldr (\x y -> x && y) True xs
-- Checks if a list of Booleans contains
-- any True
function or : [Boolean] -> Boolean
or xs := foldr (\x y -> x || y) False xs
--- Check if any element of a list
-- satisfies the predicate.
function any : atoBoolean -> [a] -> Boolean
any f xs := or (map f xs)
-- Check if all element of a list
-- satisfies the predicate.
function all : atoBoolean -> [a] -> Boolean
all f xs := and (map f xs)
-- ------------------------------------------
-- Functions over tuples
-- ------------------------------------------
-- Returns the first element in the tuple
function fst : (a,b) -> a
fst (x,y) := x
-- -- Returns the second element in the tuple
function snd : (a,b) -> b
snd (x,y) := y
-- Returns the maximum of the two elements
-- in the tuple
function max : (a,a) -> a
max (x,y)
:= x when x > y
:= y
-- Returns the minimum of the two elements
-- in the tuple
function min : (a,a) -> a
min (x,y)
:= x when x < y
:= y
-- ------------------------------------------
-- Functions over lists
-- ------------------------------------------
-- Returns the first elements in the list
function head : [a] -> a
head [] := undefined
head (x:xs) := x
-- Returns the list of all elements except
-- for the last in the input list
function init : [a] -> [a]
init [] := undefined
init (x:[]) := []
init (x:xs) := x:(init xs)
-- Returns the list of all elements except
-- for the first in the input list
function tail : [a] -> [a]
tail [] := undefined
tail (x:xs) := xs
-- Returns the last elements in the list
function last : [a] -> a
last [] := undefined
last (x:[]) := x
last (x:xs) := last xs
-- Returns the n first elements of the list
function take : Int -> [a] -> [a]
take n [] := []
take 0 _ := []
take n (x:xs) := x:(take (n-1) xs)
-- Returns the list consisting of all elements
-- that occur before the first element failing
-- the predicate
function takeWhile : (a -> Boolean) -> [a] -> [a]
takeWhile _ [] := []
takeWhile f (x:xs)
:= (x:(takeWhile f xs)) when f x
:= []
-- Returns all except the n first elements of
-- the list
function drop : Int -> [a] -> [a]
drop _ [] := []
drop 0 xs := xs
drop n (x:xs) := drop (n-1) xs
-- Returns the list consisting of all elements
-- that occur after the first element failing
-- the predicate (including that element)
function dropWhile : (a -> Boolean) -> [a] -> [a]
dropWhile _ [] := []
dropWhile f (x:xs)
:= dropWhile f xs when f x
:= (x:xs)
-- Returns the length of the list
function length : [a] -> Int
length [] := 0
length (x:xs) := 1 + length xs
-- Returns the reversed list
function reverse : [a] -> [a]
reverse [] := []
reverse (x:xs) := reverse xs ++ [x]
-- Returns true if the given value is an element
-- in the list, otherwise false.
-- function elem : [a] -> a -> Boolean
-- elem xs := any (\x y -> x==y) xs
-- Returns the sum of all elements of the list
function sumList : [a] -> a
sumList xs := foldr (\x y -> x+y) 0 xs
-- Returns the greatest element of the list
function maximum : [a] -> a
maximum (x:[]) := x
maximum (x:xs)
:= maximum xs when x < head xs
:= maximum (x:(tail xs))
-- Returns the smallest element of the list
function minimum : [a] -> a
minimum (x:[]) := x
minimum (x:xs)
:= minimum xs when x > head xs
:= minimum (x:(tail xs))
-- Returns the elements satisfying the
-- predicate
function filter : atoBoolean -> [a] -> [a]
filter _ [] := []
filter f (x:xs)
:= x:(filter f xs) when (f x)
:= filter f xs
function concat : [a] -> [a] -> [a]
concat [] ys := ys
concat (x:xs) ys := x:(concat xs ys)
function map : atob -> [a] -> [b]
map f (x:xs) := (f x):(map f xs)
map f [] := []
function foldr : atobtob -> b -> [a] -> b
foldr _ b [] := b
foldr f b (x:xs) := f x (foldr f b xs)
-- Folds a list from the left
function foldl : atobtob -> b -> [a] -> b
foldl _ a [] := a
foldl f a (x:xs) := foldl f (f a x) xs
-- Zips together two lists to a list of tuples
function zip : [a] -> [b] -> [(a,b)]
zip [] _ := []
zip _ [] := []
zip (x:xs) (y:ys) := (x,y):(zip xs ys)
-- Unzips a list of tuples to a tuple of lists
function unzip : [(a,b)] -> ([a], [b])
unzip [] := ([], [])
unzip ((x,y):xys) := ((x:(fst (unzip xys))),
(y:(snd (unzip xys))))
-- Applies the function on the corresponding elements
-- in the input lists and returns the list of the
-- values returned by the function
function zipWith : (a -> b -> c) -> [a] -> [b] -> [c]
zipWith _ [] _ := []
zipWith _ _ [] := []
zipWith f (x:xs) (y:ys) := (f x y):(zipWith f xs ys)
-- print takes a list of characters and calls printChar one every element
function print : [Char] -> (IO Char)
print [] := printChar '\n'
print (c:cs) := printChar c >> print cs