egison-3.9.4: nons-test/test/syntax.egi
--
-- Syntax test
--
--
-- Primitive Data
--
assertEqual "char literal"
['a', '\n', '\'']
['a', '\n', '\'']
assertEqual "string literal" "" ""
assertEqual "string literal" "abc\n" "abc\n"
assertEqual "bool literal"
[True, False]
[True, False]
assertEqual "integer literal"
[1, 0, -100, 1 - 100]
[1, 0, -100, -99]
assertEqual "rational number"
[10 / 3, 10 / 20, -1 / 2]
[10 / 3 , 1 / 2, -1 / 2]
assertEqual "float literal" [1.0, 0.0, -100.012001, 1.0 + 2] [1.0, 0.0, -100.012001, 3.0]
assertEqual "inductive data literal" A A
assertEqual "tuple literal" (1, 2, 3) (1, 2, 3)
assertEqual "singleton tuple literal" (1) 1
assertEqual "collection literal" [1, 2, 3, 4, 5, 6] [1, 2, 3, 4, 5, 6]
assertEqual "collection between" [1..5] [1, 2, 3, 4, 5]
assertEqual "collection from" (take 5 [1..]) [1, 2, 3, 4, 5]
--
-- Basic Sytax
--
assertEqual "if"
(if True then True else False)
True
assertEqual "if"
(if False then True else False)
False
assertEqual "let binding"
(let t = (1, 2)
(x, y) = t
in x + y)
3
assertEqual "let binding"
(let x = 1
y = x + 1
in y)
2
assertEqual "mutual recursion"
(let even? n = if n == 0 then True else odd? (n - 1)
odd? n = if n == 0 then False else even? (n - 1)
in even? 10)
True
assertEqual "lambda and application"
((\x -> x + 1) 10)
11
assertEqual "application with binops"
((\x y -> x + y) 1 2 + 3)
6
assertEqual "append op" ([1] ++ [2]) [1, 2]
assertEqual "append op" ((++) [1] [2]) [1, 2]
assertEqual "point free expr" ((+) 10 1) 11
assertEqual "point free expr" ((+ 1) 10) 11
assertEqual "point free expr" (foldl (*) 1 [1..5]) 120
assertEqual "point free expr" ((10 -) 1) 9
assertEqual "point free expr" ((10 - ) 1) 9
assertEqual "not point free expr" (- 2) (1 - 3)
-- findFactor = memoizedLambda
-- n -> match takeWhile (<= floor (sqrt (itof n))) primes as list integer with
-- | _ ++ (?(\m -> divisor? n m) && $x) : _ -> x
-- | _ -> n
-- assertEqual "memoized lambda"
-- (map findFactor [1..10])
-- [1, 2, 3, 2, 5, 2, 7, 2, 3, 2]
twinPrimes =
matchAll primes as list integer with
| _ ++ $p : #(p + 2) : _ -> (p, p + 2)
assertEqual "twin primes"
(take 10 twinPrimes)
[(3, 5), (5, 7), (11, 13), (17, 19), (29, 31), (41, 43), (59, 61), (71, 73), (101, 103), (107, 109)]
someFunction x y z =
x + y * z
assertEqual "function definition"
(someFunction 1 2 3)
7
gcd m n =
if (m >= n) then
if (n == 0) then m
else gcd n (m % n)
else gcd n m
assertEqual "recursive function definition"
(gcd 143 22)
11
--
-- Pattern-Matching
--
assertEqual "match"
(match 1 as integer with
| #0 -> 0
| $x -> 10 + x)
11
assertEqual "match-all"
(matchAll [1, 2, 3] as multiset integer with
| $x : _ -> x)
[1, 2, 3]
assertEqual "match-all-multi"
(matchAll [1, 2, 3] as multiset integer with
| $x : #(x + 1) : _ -> [x, x + 1]
| $x : #(x + 2) : _ -> [x, x + 2])
[[1, 2], [2, 3], [1, 3]]
assertEqual "match-lambda"
((\match as list integer with
| [] -> 0
| $x : _ -> x) [1, 2, 3])
1
assertEqual "match-all-lambda"
((\matchAll as list something with
| _ ++ $x : _ -> x) [1, 2, 3])
[1, 2, 3]
assertEqual "match-all-lambda-multi"
((\matchAll as multiset something with
| $x : #(x + 1) : _ -> [x, x + 1]
| $x : #(x + 2) : _ -> [x, x + 2]) [1, 2, 3])
[[1, 2], [2, 3], [1, 3]]
assert "nested pattern match"
(match [1, 2, 3] as list integer with
| #2 : $x -> match x as multiset integer with
| _ -> False
| #1 : $x -> match x as multiset integer with
| #1 : _ -> False
| #2 : _ -> True)
assertEqual "pattern variable"
(match 1 as something with $x -> x)
1
assert "value pattern" (match 1 as integer with #1 -> True)
assert "inductive pattern"
(match [1, 2, 3] as list integer with
| snoc #3 _ -> True)
assert "and pattern"
(match [1, 2, 3] as list integer with
| #1 : _ && snoc #3 _ -> True)
assert "and pattern"
(match [1, 2, 3] as list integer with
| #1 : _ && #3 : _ -> False
| _ -> True)
assert "or pattern"
(match [1, 2, 3] as list integer with
| snoc #1 _ || snoc #3 _ -> True)
assert "or pattern"
(match [1, 2, 3] as list integer with
| #2 : _ || #1 : _ -> True)
assert "not pattern"
(match 1 as integer with
| ! #1 -> False
| ! #2 -> True)
assertEqual "not pattern"
(matchAll [1, 2, 2, 3, 3, 3] as multiset integer with
| $n : !(#n : _) -> n)
[1]
assert "predicate pattern"
(match [1, 2, 3] as list integer with
| ?(== 1) : _ -> True)
assert "predicate pattern"
(match [1, 2, 3] as list integer with
| ?(== 2) : _ -> False
| _ -> True)
assertEqual "indexed pattern variable"
(match 23 as mod 10 with
| $a_1 -> a)
{| [1, 23] |}
assert "loop pattern"
(match [3, 2, 1] as list integer with
| loop $i (1, [3], _)
| snoc #i ...
| [] -> True)
assertEqual "loop pattern"
(match [1..10] as list integer with
| loop $i (1, $n)
| #i : ...
| [] -> n)
10
assert "loop pattern"
(match [3, 2, 1] as list integer with
| loop $i (1, [3], _)
| snoc #i ...
| [] -> True)
assertEqual "double loop pattern"
(match [[1, 2, 3], [4, 5, 6], [7, 8, 9]] as (list (list integer)) with
| loop $i (1, [3], _)
| ((loop $j (1, [3], _)
| $n_i_j : ...
| []) : ...)
| [] -> n)
{| [1, {| [1, 1], [2, 2], [3, 3] |}],
[2, {| [1, 4], [2, 5], [3, 6] |}],
[3, {| [1, 7], [2, 8], [3, 9] |}] |}
assertEqual "let pattern"
(match [1, 2, 3] as list integer with
| let a = 42 in _ -> a)
42
assertEqual "let pattern"
(match [1, 2, 3] as list integer with
| $a : (let x = a in $xs) -> [x, xs])
[1, [2, 3]]
assertEqual "let pattern"
(match [1, 2, 3] as list integer with
| $a && (let n = length a in _) -> [a, n])
[[1, 2, 3], 3]
assertEqual "tuple pattern"
(matchAll (1, (2, 3)) as (integer, (integer, integer)) with
| ($m, ($n, $w)) -> [m, n, w])
[[1, 2, 3]]
assertEqual "tuple pattern"
(matchAll [(1, 1), (2, 2)] as multiset (integer, integer) with
| ($x, #x) : _ -> x)
[1, 2]
-- assertEqual "pattern function call"
-- (let twin = \pat1 pat2 => (~pat1 && $x) : #x : ~pat2 in
-- match [1, 1, 1, 2, 3] as list integer with
-- | twin $n $ns -> [n, ns])
-- [1, [1, 2, 3]]
-- assertEqual "recursive pattern function call"
-- (let repeat = \pat => [] || (~pat && $x) : (repeat x) in
-- match [1, 1, 1, 1] as list integer with
-- | repeat $n -> n)
-- 1
-- assertEqual "loop pattern in pattern function"
-- let comb n = \p =>
-- loop $i (1, n, _) _ ++ ~p_i : ... | _
-- in
-- matchAll [1, 2, 3, 4, 5] as (list integer) with
-- | (comb 2) $n -> n
-- [{|[1, 1], [2, 2]|}, {|[1, 1], [2, 3]|}, {|[1, 2], [2, 3]|}, {|[1, 1], [2, 4]|}, {|[1, 2], [2, 4]|}, {|[1, 3], [2, 4]|}, {|[1, 1], [2, 5]|}, {|[1, 2], [2, 5]|}, {|[1, 3], [2, 5]|}, {|[1, 4], [2, 5]|}]
assertEqual "pairs of 2, natural numbers"
(take 10 (matchAll nats as set integer with
| $m : $n : _ -> [m, n]))
[[1, 1], [1, 2], [2, 1], [1, 3], [2, 2], [3, 1], [1, 4], [2, 3], [3, 2], [4, 1]]
assertEqual "pairs of 2, different natural numbers"
(take 10 (matchAll nats as list integer with
| _ ++ $m : _ ++ $n : _ -> [m, n]))
[[1, 2], [1, 3], [2, 3], [1, 4], [2, 4], [3, 4], [1, 5], [2, 5], [3, 5], [4, 5]]
tree a = algebraicDataMatcher
| leaf
| node (tree a) a (tree a)
treeInsert n t =
match t as tree integer with
| leaf -> Node Leaf n Leaf
| node $t1 $m $t2 -> match (compare n m) as ordering with
| less -> Node (treeInsert n t1) m t2
| equal -> Node t1 n t2
| greater -> Node t1 m (treeInsert n t2)
treeMember? n t =
match t as tree integer with
| leaf -> False
| node $t1 $m $t2 -> match (compare n m) as ordering with
| less -> treeMember? n t1
| equal -> True
| greater -> treeMember? n t2
assertEqual "tree set using algebraic-data-matcher"
(let t = foldr treeInsert Leaf [4, 1, 2, 4, 3]
in [treeMember? 1 t, treeMember? 0 t])
[True, False]
assert "sequential pattern"
(match [2,3,1,4,5] as list integer with
{ @ : @ : $x : _,
(#(x + 1), @),
#(x + 2)} -> True)
--
-- Tensor
--
assertEqual "generate-tensor"
(generateTensor (*) [3, 5])
[| [| 1, 2, 3, 4, 5 |], [| 2, 4, 6, 8, 10 |], [| 3, 6, 9, 12, 15 |] |]
assertEqual "tensor"
(tensor [2, 5] [1, 2, 3, 4, 5, 2, 4, 6, 8, 10])
[| [| 1, 2, 3, 4, 5 |], [| 2, 4, 6, 8, 10 |] |]
assertEqual "tensor wedge expr"
(! b.min [| 1, 2, 3 |] [| 1, 2, 3 |])
[| [| 1, 1, 1 |], [| 1, 2, 2 |], [| 1, 2, 3 |] |]
assertEqual "tensor wedge expr of binary operator"
([| 1, 2, 3 |] !+ [| 1, 2, 3 |])
[| [| 2, 3, 4 |], [| 3, 4, 5 |], [| 4, 5, 6 |] |]
assertEqual "tensor multiplication"
([| 1, 2, 3 |]_i * [| 1, 2, 3 |]_i)
[| 1, 4, 9 |]_i
--
-- Hash
--
assertEqual "hash-literal"
{| [1, 11], [2, 12], [3, 13], [4, 14], [5, 15], |}
{| [1, 11], [2, 12], [3, 13], [4, 14], [5, 15], |}
assertEqual "empty hash-literal"
{| |}
{| |}
assertEqual "hash access"
{| [1, 11], [2, 12], [3, 13], [4, 14], [5, 15], |}_3
13
--
-- Partial Application
--
-- assertEqual "partial application '$'"
-- ($ + $)(1, 2)
-- 3
--
-- assertEqual "partial application '$' with index"
-- ($2-$1)(1, 2)
-- 1
--
-- assertEqual "partial application '#'"
-- 2#(10 * %1 + %2)(1, 2)
-- 12
--
-- assertEqual "recursive partial application '#'"
-- take(10, 1#[%1, @(%0(%1 * 2))](2))
-- [2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
f *x *y = x + y
assertEqual "double inverted index"
(f [|1, 2, 3|]_i [|10, 20, 30|]_j)
[| [| 11, 21, 31, |], [| 12, 22, 32, |], [| 13, 23, 33, |], |]~i~j
g x *y = x + y
assertEqual "single inverted index"
(g [|1, 2, 3|]_i [|10, 20, 30|]_j)
[| [| 11, 21, 31, |], [| 12, 22, 32, |], [| 13, 23, 33, |], |]_i~j
--
-- matcherExpr, macroExpr
--
list a = matcher
| [] as () with
| [] -> [()]
| _ -> []
| $ : $ as (a, list a) with
| $x : $xs -> [(x, xs)]
| _ -> []
| snoc $ $ as (a, list a) with
| snoc $xs $x -> [(x, xs)]
| _ -> []
| join _ $ as (list a) with
| $tgt -> matchAll tgt as list a with
| loop $i (1, _) | _ : ... | $rs -> rs
| join $ $ as (list a, list a) with
| $tgt -> matchAll tgt as list a with
| loop $i (1, $n) $xa_i : ... | $rs ->
(foldr (\%i %r -> xa_i : r) [] [1..n], rs)
| nioj $ $ as (list a, list a) with
| $tgt -> matchAll tgt as list a with
| loop $i (1, $n) snoc $xa_i ... | $rs ->
(foldr (\%i %r -> r ++ [xa_i]) [] [1..n], rs)
| #$val as () with
| $tgt -> if val == tgt then [()] else []
| $ as something with
| $tgt -> [tgt]
multiset a = matcher
| [] as () with
| $tgt -> match tgt as (mutiset a) with
| [] -> [()]
| _ -> []
| $ : $ as (a, multiset a) with
| $tgt -> matchAll tgt as list a with
| $hs ++ $x : $ts -> (x, hs ++ ts)
| #$val as () with
| $tgt -> match (val, tgt) as (list a, multiset a) with
| ([], []) -> [()]
| ($x : $xs, #x : #xs) -> [()]
| (_, _) -> []
| $ as something with
| $tgt -> [tgt]
assertEqual "matcher definition"
(matchAll [1, 2, 3] as multiset integer with
| $x : _ -> x)
[1, 2, 3]
nishiwakiIf =
macro b e1 e2 ->
car (matchAll b as (matcher
| $ as something with
| True -> [e1]
| False -> [e2]) with
| $x -> x)
assertEqual "case 1" (nishiwakiIf True 1 2) 1
assertEqual "case 2" (nishiwakiIf False 1 2) 2
assertEqual "case 3" (nishiwakiIf (1 == 1) 1 2) 1