egison-0.1: sample/list-test.egi
(define $Something
(type
{[$var-match (lambda [$tgt] {tgt})]
}))
(define $Suit
(type
{[$var-match (lambda [$tgt] {tgt})]
[$inductive-match
(deconstructor
{[spade []
{[<spade> {[]}]
[_ {}]}]
[heart []
{[<heart> {[]}]
[_ {}]}]
[club []
{[<club> {[]}]
[_ {}]}]
[diamond []
{[<diamond> {[]}]
[_ {}]}]
})]
[$=
(lambda [$val $tgt]
(match [val tgt] [Card Card]
{[[<spade> <spade>] <true>]
[[<heart> <heart>] <true>]
[[<club> <club>] <true>]
[[<diamond> <diamond>] <true>]
[[_ _] <false>]}))]
}))
(test (match-map <club> Suit [<club> <ok>]))
(define $Nat
(type
{[$var-match (lambda [$tgt] {tgt})]
[$inductive-match
(deconstructor
{[o []
{[<o> {[]}]
[_ {}]
}]
[s [Nat]
{[<s $x> {x}]
[_ {}]
}]
})]
[$=
(lambda [$val $tgt]
(match [val tgt] [Nat Nat]
{[[<o> <o>] <true>]
[[<s $n1> <s $n2>] (= n1 n2)]
[[_ _] <false>]}))]
}))
(define $monus
(lambda [$m $n]
(match [m n] [Nat Nat]
{[[_ <o>] m]
[[<o> _] <o>]
[[<s $m1> <s $n1>] (monus m1 n1)]})))
(test (monus <s <s <o>>> <s <o>>))
(define $mod
(lambda [$m $n]
(match (monus m n) Nat
{[<o> m]
[$m1 (mod m1 n)]})))
(test (mod <s <s <s <s <o>>>>> <s <s <s <o>>>>))
(define $Mod
(lambda [$m]
(let {[$Loop
(type {[$var-match (lambda [$tgt] {tgt})]
[$inductive-match
(deconstructor
{[o []
{[<o> {[]}]
[_ {}]
}]
[s [Loop]
{[<s $x> {x}]
[<o> {m}]
}]})]
[$= (lambda [$val $tgt]
((type-ref Nat =) (mod val m) tgt))]})]}
(type
{[$var-match (lambda [$tgt] {(mod tgt m)})]
[$inductive-match
(lambda [$tgt]
((type-ref Loop inductive-match) (mod tgt m)))]
[$= (lambda [$val $tgt]
((type-ref Nat =) (mod val m) (mod tgt m)))]}))))
(test (match <s <s <s <s <o>>>>> (Mod <s <s <s <o>>>>)
{[<o> <not-ok>]
[<s <o>> <ok>]
[<s <s <o>>> <not-ok>]}))
(define $List
(lambda [$a]
(type
{[$var-match (lambda [$tgt] {tgt})]
[$inductive-match
(deconstructor
{[nil []
{[{} {[]}]
[_ {}]
}]
[cons [a (List a)]
{[{$x .$xs} {[x xs]}]
[_ {}]
}]
[snoc [a (List a)]
{[{.$xs $x} {[x xs]}]
[_ {}]
}]
[join [(List a) (List a)]
{[$tgt (let {[$loop
(lambda [$ts]
(match ts (List a)
{[<nil> {[{} {}]}]
[<cons $x $xs>
{[{} ts]
@(map (lambda [$as $bs]
[{x @as} bs])
(loop xs))}]}))]}
(loop tgt))]
}]
[nioj [(List a) (List a)]
{[$tgt (let {[$loop
(lambda [$ts]
(match ts (List a)
{[<nil> {[{} {}]}]
[<snoc $x $xs>
{[{} ts]
@(map (lambda [$as $bs]
[{@as x} bs])
(loop xs))}]}))]}
(loop tgt))]
}]
})]
[$= (lambda [$val $tgt]
(match [val tgt] [(List a) (List a)]
{[[<nil> <nil>] <true>]
[[<cons $x $xs>
<cons (on [$x] ,x) (on [$xs] ,xs)>]
<true>]
[[_ _] <false>]}))]
})))
(test ((type-ref (List Nat) =) {<o> <s <o>>} {<o> <s <o>>}))
(test (match-map {<o> <s <o>> <s <s <o>>>} (List Nat) [<snoc $x $xs> [x xs]]))
(test (match-map {<o> <s <o>> <s <s <o>>>} (List Nat) [<nioj $xs $ys> [xs ys]]))
(define $map
(lambda [$fn $ls]
(match ls (List Something)
{[<nil> {}]
[<cons $x $xs> {(fn x) @(map fn xs)}]})))
(test (map (lambda [$a] <s a>) {<o> <s <o>>}))
(test (match {} (List Something)
{[<join $hs $ts> [hs ts]]}))
(test (match-map {<x> <y>} (List Something)
[<join $hs $ts> [hs ts]]))
(test (match-map {<x> <y> <z> <w>} (List Something)
[<join $hs <cons $x $ts>> [hs x ts]]))
(define $remove
(lambda [$a]
(lambda [$xs $x]
(match xs (List a)
{[<nil> {}]
[<cons x $rs> rs]
[<cons $y $rs> {y @((remove a) rs x)}]}))))
(test ((remove Nat) {<o> <s <o>>} <o>))
(define $remove-collection
(lambda [$a]
(lambda [$xs $ys]
(match ys (List a)
{[<nil> xs]
[<cons $y $rs> ((remove-collection a) ((remove a) xs y) rs)]}))))
(test ((remove-collection Nat) {<o> <s <o>> <s <s <o>>>} {<o> <s <s <o>>>}))
(define $subcollection
(lambda [$xs]
(match xs (List Something)
{[<nil> {{}}]
[<cons $x $rs>
(let {[$subs (subcollection rs)]}
{@subs @(map (lambda [$sub] {x @sub})
subs)})]
})))
(test (subcollection {<o> <s <o>> <s <s <o>>>}))
(define $Multiset
(lambda [$a]
(type
{[$var-match (lambda [$tgt] {tgt})]
[$inductive-match
(deconstructor
{[nil []
{[{} {[]}]
[_ {}]
}]
[cons [a (Multiset a)]
{[$tgt (map (lambda [$t] [t ((remove a) tgt t)])
tgt)]
}]
[join [(Multiset a) (Multiset a)]
{[$tgt (map (lambda [$ts] [ts ((remove-collection a) tgt ts)])
(subcollections tgt))]
}]
})]
[$= (lambda [$val $tgt]
(match [val tgt] [(Multiset a) (Multiset a)]
{[[<nil> <nil>] <true>]
[[<cons $x $xs>
<cons (on [$x] x) (on [$xs] xs)>]
<true>]
[[_ _] <false>]}))]
})))
(define $one-pair
(lambda [$ns]
(match ns (Multiset Nat)
{[<cons $m
<cons (on [$m] m)
_>>
<ok>]
[_ <nothing>]
})))
(test (one-pair {<o> <s <o>> <o>}))
(define $full-house
(lambda [$ns]
(match ns (Multiset Nat)
{[<cons $m
<cons (on [$m] m)
<cons (on [$m] m)
!<cons $n
!<cons (on [$n] n)
!<nil>
>>>>>
<full-house>]
[_ <nothing>]
})))
(test (full-house {<o> <o> <s <o>> <o> <s <o>>}))
(define $thirteen <s <s <s <s <s <s <s <s <s <s <s <s <s <o>>>>>>>>>>>>>>)
(define $Card
(type
{[$var-match (lambda [$tgt] {tgt})]
[$inductive-match
(deconstructor
{[card [Suit (Mod thirteen)]
{[<card $s $n> {[s n]}]}]})]
[$= <undefined>]}))
(define $poker-hands
(lambda [$Cs]
(match Cs (Multiset Card)
{[<cons <card $S $n>
<cons <card (on [$S] ,S) (on [$n] ,(- n 1))>
<cons <card (on [$S] ,S) (on [$n] ,(- n 2))>
<cons <card (on [$S] ,S) (on [$n] ,(- n 3))>
<cons <card (on [$S] ,S) (on [$n] ,(- n 4))>
!<nil>
>>>>>
<straight-flush>]
[<cons <card _ $n>
<cons <card _ (on [$n] ,n)>
!<cons <card _ (on [$n] ,n)>
!<cons <card _ (on [$n] ,n)>
!<cons _
!<nil>
>>>>>
<four-of-kind>]
[<cons <card _ $m>
<cons <card _ (on [$m] ,m)>
<cons <card _ (on [$m] ,m)>
!<cons <card _ $n>
!<cons <card _ (on [$n] ,n)>
!<nil>
>>>>>
<full-house>]
[<cons <card $S _>
!<cons <card (on [$S] ,S) _>
!<cons <card (on [$S] ,S) _>
!<cons <card (on [$S] ,S) _>
!<cons <card (on [$S] ,S) _>
!<nil>
>>>>>
<flush>]
[<cons <card _ $n>
<cons <card _ (on [$n] ,(- n 1))>
<cons <card _ (on [$n] ,(- n 2))>
<cons <card _ (on [$n] ,(- n 3))>
<cons <card _ (on [$n] ,(- n 4))>
!<nil>
>>>>>
<straight>]
[<cons <card _ $n>
<cons <card _ (on [$n] ,n)>
<cons <card _ (on [$n] ,n)>
!<cons _
!<cons _
!<nil>
>>>>>
<three-of-kind>]
[<cons <card _ $m>
<cons <card _ (on [$m] ,m)>
!<cons <card _ $n>
<cons <card _ (on [$n] ,n)>
!<cons _
!<nil>
>>>>>
<two-pair>]
[<cons <card _ $n>
<cons <card _ (on [$n] ,n)>
!<cons _
!<cons _
!<cons _
!<nil>
>>>>>
<one-pair>]
[<cons _
!<cons _
!<cons _
!<cons _
!<cons _
!<nil>
>>>>>
<nothing>]})))
(define $poker-hands-without-strait
(lambda [$Cs]
(match Cs (Multiset Card)
{[<cons <card _ $n>
<cons <card _ (on [$n] ,n)>
!<cons <card _ (on [$n] ,n)>
!<cons <card _ (on [$n] ,n)>
!<cons _
!<nil>
>>>>>
<four-of-kind>]
[<cons <card _ $m>
<cons <card _ (on [$m] ,m)>
<cons <card _ (on [$m] ,m)>
!<cons <card _ $n>
!<cons <card _ (on [$n] ,n)>
!<nil>
>>>>>
<full-house>]
[<cons <card $S _>
!<cons <card (on [$S] ,S) _>
!<cons <card (on [$S] ,S) _>
!<cons <card (on [$S] ,S) _>
!<cons <card (on [$S] ,S) _>
!<nil>
>>>>>
<flush>]
[<cons <card _ $n>
<cons <card _ (on [$n] ,n)>
<cons <card _ (on [$n] ,n)>
!<cons _
!<cons _
!<nil>
>>>>>
<three-of-kind>]
[<cons <card _ $m>
<cons <card _ (on [$m] ,m)>
!<cons <card _ $n>
<cons <card _ (on [$n] ,n)>
!<cons _
!<nil>
>>>>>
<two-pair>]
[<cons <card _ $n>
<cons <card _ (on [$n] ,n)>
!<cons _
!<cons _
!<cons _
!<nil>
>>>>>
<one-pair>]
[<cons _
!<cons _
!<cons _
!<cons _
!<cons _
!<nil>
>>>>>
<nothing>]})))
(test (poker-hands-without-strait {<card <diamond> <o>>
<card <club> <s <o>>>
<card <club> <o>>
<card <heart> <o>>
<card <diamond> <s <o>>>}))
(define $car
(lambda [$as]
(match as (List Something)
{[<cons $a _> a]})))
(define $reverse
(lambda [$as]
(match as (List Something)
{[<nil> {}]
[<cons $a $rs>
{@(reverse rs) a}]})))