packages feed

egison-0.1.2.5: etc/sample/collection-test.egi

(define $Bool
  (type
    {[$var-match (lambda [$tgt] {tgt})]
     [$inductive-match
      (deconstructor
        {[true []
          {[<true> {[]}]
           [_ {}]}]
         [false []
          {[<false> {[]}]
           [_ {}]}]
         })]
     [$equal?
      (lambda [$val $tgt]
        (match [val tgt] [Bool Bool]
          {[[<true> <true>] <true>]
           [[<false> <false>] <true>]
           [[_ _] <false>]}))]
     }))

(define $Order
  (type
    {[$var-match (lambda [$tgt] {tgt})]
     [$inductive-match
      (deconstructor
        {[less []
          {[<equal> {[]}]
           [_ {}]}]
         [equal []
          {[<equal> {[]}]
           [_ {}]}]
         [greater []
          {[<greater> {[]}]
           [_ {}]}]
         })]
     [$equal?
      (lambda [$val $tgt]
        (match [val tgt] [Order Order]
          {[[<less> <less>] <true>]
           [[<equal> <equal>] <true>]
           [[<greater> <greater>] <true>]
           [[_ _] <false>]}))]
     }))

(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> {[]}]
           [_ {}]}]
         })]
     [$equal?
      (lambda [$val $tgt]
        (match [val tgt] [Suit Suit]
          {[[<spade> <spade>] <true>]
           [[<heart> <heart>] <true>]
           [[<club> <club>] <true>]
           [[<diamond> <diamond>] <true>]
           [[_ _] <false>]}))]
     }))

(define $Nat
  (type
    {[$var-match (lambda [$tgt] {tgt})]
     [$equal? (lambda [$val $tgt]
                (= val tgt))]}))

(define $Int
  (type
    {[$var-match (lambda [$tgt] {tgt})]
     [$equal? (lambda [$val $tgt]
                (= val tgt))]
     }))

(define $Mod
  (lambda [$m]
    (type
      {[$var-match (lambda [$tgt] {(mod tgt m)})]
       [$equal? (lambda [$val $tgt]
                  (= (mod val m) (mod tgt m)))]})))

(define $Card
  (type
    {[$var-match (lambda [$tgt] {tgt})]
     [$inductive-match
      (deconstructor
        {[card [Suit (Mod 13)]
          {[<card $s $n> {[s n]}]}]})]
     [$equal? (lambda [$val $tgt]
                (match [val tgt] [Card Card]
                  {[[<card $s $n>
                     <card (on [$s] ,s) (on [$n] ,n)>]
                    <true>]
                   [[_ _] <false>]}))]}))

(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))]
             }]
           })]
       [$equal? (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>]}))]
       })))

(define $map
  (lambda [$fn $ls]
    (match ls (List Something)
      {[<nil> {}]
       [<cons $x $xs> {(fn x) @(map fn xs)}]})))

(define $remove
  (lambda [$a]
    (lambda [$xs $x]
      (match xs (List a)
        {[<nil> {}]
         [<cons ,x $rs> rs]
         [<cons $y $rs> {y @((remove a) rs x)}]}))))

(define $remove-all
  (lambda [$a]
    (lambda [$xs $x]
      (match xs (List a)
        {[<nil> {}]
         [<cons ,x $rs> ((remove-all a) rs x)]
         [<cons $y $rs> {y @((remove-all a) rs x)}]}))))

(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)]}))))

(define $subcollections
  (lambda [$xs]
    (match xs (List Something)
      {[<nil> {{}}]
       [<cons $x $rs>
        (let {[$subs (subcollections rs)]}
          {@subs @(map (lambda [$sub] {x @sub})
                       subs)})]
       })))

(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))]
             }]
           })]
       [$equal? (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 $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 $min
  (lambda [$Ns]
    (match Ns (List Int)
      {[<cons $n <nil>> n]
       [<cons $n $Rs>
        (let {[$r (min Rs)]}
          (match ((type-ref Int compare) n r) Order
            {[<less> n]
             [_ r]}))]})))       

(define $gcd
  (lambda [$ns]
    (let {[$ns2 ((remove-all Int) ns 0)]}
      (match ns2 (Set Int)
        {[<cons $n <nil>> n]
         [<cons ,(min ns2)
                $Rs>
          (gcd {n @(map (lambda [$r] (mod r n))
                        Rs)})]}))))

(define $gcd
  (lambda [$Ns]
    (let {[$Ns2 (remove-all Ns 0)]}
      (match Ns2 (Set Int)
        {[<cons $n <nil>> n]
         [<cons ,(min Ns2)
                $Rs>
          (gcd {n @(map (lambda [$r] (mod r n))
                        Rs)})]}))))

(define $car
  (lambda [$xs]
    (match xs (List Something)
      {[<cons $x _> x]})))

(define $reverse
  (lambda [$xs]
    (match xs (List Something)
      {[<nil> {}]
       [<cons $x $rs>
        {@(reverse rs) x}]})))

(define $member?
  (lambda [$a]
    (lambda [$x $ys]
      (match ys (List a)
        {[<nil> <false>]
         [<cons ,x $ys> <true>]
         [<cons $y $ys> ((member? a) x ys)]
         }))))

(define $unique
  (lambda [$a]
    (lambda [$xs]
      (let {[$loop (lambda [$xs $ys]
                     (match xs (List a)
                       {[<nil> ys]
                        [<cons $x $rs>
                         (match ((member? a) x ys) Bool
                           {[<true> (loop rs ys)]
                            [<false> (loop rs {@ys x})]
                            [_ {}]
                            })]}))]}
        (loop xs {})))))

(define $Set
  (lambda [$a]
    (let
      {[$Loop
        (type
          {[$var-match
            (lambda [$ts1 $ts2]
              (map (lambda [$sts2] {@ts1 @sts2})
                   (subcollections ts2)))]
           [$inductive-match
            (deconstructor
              {[nil []
                {[[{} _] {[]}]
                 [[_ _] {}]
                 }]
               [cons [a Loop]
                {[[$ts1 $ts2]  (map (lambda [$t] [t [((remove a) ts1 t)
                                                     {@ts2 t}]])
                                    {@ts1 @ts2})]
                 }]
               [join [(Set a) Loop]
                {[[$ts1 $ts2] (map (lambda [$ts] [ts [((remove-collection a) ts1 ts)
                                                      {@ts2 ts}]])
                                   (subcollections {@ts1 @ts2}))]
                 }]
               })]
           [$equal? <undefined>]
           })]}
      (type
        {[$var-match (lambda [$tgt] {$tgt})]
         [$inductive-match
          (lambda [$tgt]
            (let {[$tgt2 ((unique a) tgt)]}
              ((type-ref Loop inductive-match) [tgt2 {}])))]
         [$equal? <undefined>]}))))

(define $not
  (lambda [$b]
    (match b Bool
      {[<true> <false>]
       [<false> <true>]})))

(define $ham1
  (lambda [$xs $ys]
    (match [xs ys] [(List Bool) (List Bool)]
      {[[<join $hs <cons $x $ts>>
         <join (on [$hs] ,hs) <cons (on [$x] ,(not x)) (on [$ts] ,ts)>>]
        <true>]
       [[_ _] <false>]})))

(define $ham1
  (lambda [$xs $ys]
    (match [xs ys] [(List Bool) (List Bool)]
      {[[<join $hs <cons $x $ts>>
         <join (on [$hs] ,{}) <cons (on [$x] ,(not x)) (on [$ts] ,{})>>]
        <true>]
       [[_ _] <false>]})))

(test (match-map {<x> <y> <z>} (List Something) [<nioj $xs $ys> [xs ys]]))

(test (match-map {<x> <y> <z> <w>} (List Something)
        [<join $hs <cons $x $ts>> [hs x ts]]))

(test (match-map {<x> <y> <z>} (Multiset Something)
        [<join $hs  $ts> [hs x ts]]))

(test (match-map {<x> <y> <z>} (Set Something)
        [<join $hs $ts> [hs ts]]))

(test ((remove-collection Suit) {<club> <heart> <diamond>} {<club> <diamond>}))

(test (subcollections {<x> <y> <z>}))

(test (poker-hands {<card <club> 4>
                    <card <club> 2>
                    <card <club> 5>
                    <card <club> 1>
                    <card <club> 3>}))

(test (poker-hands {<card <diamond> 1>
                    <card <club> 2>
                    <card <club> 1>
                    <card <heart> 1>
                    <card <diamond> 2>}))

(test (poker-hands {<card <diamond> 4>
                    <card <club> 2>
                    <card <club> 5>
                    <card <heart> 1>
                    <card <diamond> 3>}))

(test (poker-hands {<card <diamond> 4>
                    <card <club> 10>
                    <card <club> 5>
                    <card <heart> 1>
                    <card <diamond> 3>}))