packages feed

swish-0.2.1: Swish/HaskellRDF/Sort/FingerSearchtree.lhs

%-------------------------------=  --------------------------------------------
\chapter{Finger search trees}
%-------------------------------=  --------------------------------------------

%align

> module Swish.HaskellRDF.Sort.FingerSearchtree 
> where
> import Swish.HaskellRDF.Sort.LibBase

%align 33

This is work in progress \ldots

> data Empty a			=  E
>
> data Pennant tree a		=  Top a (tree a)
>
> data Node23 tree23 a		=  N2 (tree23 a) a (tree23 a)
>				|  N3 (tree23 a) a (tree23 a) a (tree23 a) 

> data FingerTree23 tree23 a	=  Nil
>				|  One (Pennant tree23 a) (FingerTree23 (Node23 tree23) a)
>				|  Two (Pennant (Node23 tree23) a) (FingerTree23 (Node23 tree23) a)
>
> type Bag a			=  FingerTree23 Empty a

> incr						:: Pennant tree23 a -> FingerTree23 tree23 a -> FingerTree23 tree23 a
> incr p Nil					=  One p Nil
> incr (Top a1 t1) (One (Top a2 t2) ds)		=  Two (Top a1 (N2 t1 a2 t2)) ds
> incr (Top a1 t1) (Two (Top a2 (N2 t2 a3 t3)) ds)
>						=  Two (Top a1 (N3 t1 a2 t2 a3 t3)) ds
> incr (Top a1 t1) (Two (Top a2 (N3 t2 a3 t3 a4 t4)) ds)
>						=  Two (Top a1 (N2 t1 a2 t2)) (incr (Top a3 (N2 t3 a4 t4)) ds)

> data Grown tree23 a		=  U (tree23 a)  
>				|  G (tree23 a) a (tree23 a)
>
> class Ins tree23 where
>     ins			:: (Ord a) => a -> tree23 a -> Grown tree23 a

> instance Ins Empty where
>     ins a E			=  G E a E
>
> instance (Ins tree23) => Ins (Node23 tree23) where
>     ins a (N2 t1 a1 t2)
>         | a <= a1		=  node2l (ins a t1) a1 t2
>         | otherwise		=  node2r t1 a1 (ins a t2)
>     ins a (N3 t1 a1 t2 a2 t3)
>         | a <= a1		=  node3l (ins a t1) a1 t2 a2 t3
>         | a <= a2		=  node3m t1 a1 (ins a t2) a2 t3
>         | otherwise		=  node3r t1 a1 t2 a2 (ins a t3)

> node2l			:: Grown tree23 a -> a -> tree23 a -> Grown (Node23 tree23) a
> node2l (U t1) a1 t2		=  U (N2 t1 a1 t2)
> node2l (G t1 a1 t2) a2 t3	=  U (N3 t1 a1 t2 a2 t3)

> node2r t1 a1 (U t2)		=  U (N2 t1 a1 t2)
> node2r t1 a1 (G t2 a2 t3)	=  U (N3 t1 a1 t2 a2 t3)

> node3l (U t1) a1 t2 a2 t3	=  U (N3 t1 a1 t2 a2 t3)
> node3l (G t1 a1 t2)a2 t3 a3 t4=  G (N2 t1 a1 t2) a2 (N2 t3 a3 t4)

> node3m t1 a1 (U t2) a2 t3	=  U (N3 t1 a1 t2 a2 t3)
> node3m t1 a1 (G t2 a2 t3)a3 t4=  G (N2 t1 a1 t2) a2 (N2 t3 a3 t4)
>
> node3r t1 a1 t2 a2 (U t3)	=  U (N3 t1 a1 t2 a2 t3)
> node3r t1 a1 t2 a2(G t3 a3 t4)=  G (N2 t1 a1 t2) a2 (N2 t3 a3 t4)

> insert'			:: (Ord a, Ins tree23) => a -> FingerTree23 tree23 a -> Maybe (FingerTree23 tree23 a)
> insert' a Nil			=  Nothing
> insert' a (One p@(Top a1 t1) ds)
>     | a <= a1			=  Nothing
>     | otherwise		=  case insert' a ds of
>         Nothing		-> Just (one a1 (ins a t1) ds)
>         Just ds'		-> Just (One p ds')
> insert' a (Two p@(Top a1 t1) ds)
>     | a <= a1			=  Nothing
>     | otherwise		=  case insert' a ds of
>         Nothing		-> Just (two a1 (ins a t1) ds)
>         Just ds'		-> Just (Two p ds')

> one				:: a -> Grown tree23 a -> FingerTree23 (Node23 tree23) a -> FingerTree23 tree23 a
> one a1 (U t1) t2		=  One (Top a1 t1) t2
> one a1 (G t1 a2 t2) t3	=  Two (Top a1 (N2 t1 a2 t2)) t3
>
> two				:: a -> Grown (Node23 tree23) a -> FingerTree23 (Node23 tree23) a -> FingerTree23 tree23 a
> two a1 (U t1) t2		=  Two (Top a1 t1) t2
> two a1 (G t1 a2 t2) t3	=  Two (Top a1 t1) (incr (Top a2 t2) t3)

> insert			:: (Ord a) => a -> Bag a -> Bag a
> insert a t			=  case insert' a t of
>     Nothing			-> incr (Top a E) t
>     Just t'			-> t'

> class Inord tree23 where
>     inord			:: tree23 a -> Sequ a
>
> instance Inord Empty where
>     inord E			=  empty
>
> instance (Inord tree23) => Inord (Node23 tree23) where
>     inord (N2 t1 a1 t2)	=  inord t1 . single a1 . inord t2
>     inord (N3 t1 a1 t2 a2 t3)	=  inord t1 . single a1 . inord t2
>				.  single a2 . inord t3
>
> instance (Inord tree23) => Inord (Pennant tree23) where
>     inord (Top a t)		=  single a . inord t

> inorder'			:: (Inord tree23) => FingerTree23 tree23 a -> Sequ a
> inorder' Nil			=  empty
> inorder' (One p ds)		=  inord p . inorder' ds
> inorder' (Two p ds)		=  inord p . inorder' ds
>
> inorder			:: Bag a -> [a]
> inorder b			=  inorder' b []

> fingerTreeSort		:: (Ord a) => [a] -> [a]
> fingerTreeSort		=  inorder . foldr insert Nil

> type Sequ a			=  [a] -> [a]
>
> empty				=  \x -> x
>
> single a			=  \x -> a : x