Subversion

2lt

?curdirlinks? - Rev 1

?prevdifflink? - Blame



types

Space = [ S ];
S = Box | BoxSplit;
Box :: info: BoxInfo
       width: Width;
BoxSplit :: one: Space
            two: Space;

BoxInfo = token;
Width = real

values

boxA = mk_Box( mk_token("A"), 70.5 );
boxB = mk_Box( mk_token("B"), 50 );
boxC = mk_Box( mk_token("C"), 35.25 );

bs3 = mk_BoxSplit( boxC, nil );
bs2 = mk_BoxSplit( boxB, bs3 );
bs1 = mk_BoxSplit( boxA, bs2 );

s = bs1 

functions

cata[@X]: @X * (Box -> @X) * (@X * @X -> @X)  -> (Space -> @X)
cata( c, b, s )(space) ==
        if space = nil 
        then c
        elseif is_Box(space) 
        then b(space)
        else s(cata[@X](c, b, s)(space.one),cata[@X](c, b, s)(space.two));

ana[@X]: (@X -> ([Box] | @X * @X )) -> (@X -> Space)
ana(g)(x) == let res = g(x)
             in if res = nil
                then nil
                elseif is_Box(res) 
                then res
                else let mk_(res1,res2) = res
                     in mk_BoxSplit(ana[@X](g)(res1), ana[@X](g)(res2));

para[@X]: @X * (Box -> @X) * (@X * Space * @X * Space -> @X) -> (Space -> @X)
para( c, b, s )(space) == 
        if space = nil 
        then c
        else if is_Box(space)
             then b(space)
             else s(para[@X](c, b, s)(space.one), space.one,
                    para[@X](c, b, s)(space.two), space.two);

        
whichBoxes : Space -> set of BoxInfo
whichBoxes (s) == 
        cata[set of BoxInfo](
                {}, 
                lambda x : Box & {x.info}, 
                lambda x: set of BoxInfo, y: set of BoxInfo & x union y) (s);

freeSpace : Space -> Width
freeSpace( s) == freespace_aux( s, 100);

freespace_aux : Space * Width -> Width
freespace_aux( s, r) == if s = nil then r
                        elseif is_Box(s) then 0
                        else max( freespace_aux(s.one, (r*sqrt(2))/2
),
                                  freespace_aux(s.two, (r*sqrt(2))/2
));

max : Width * Width -> Width
max (x, y) == if x > y then x else y;


insertBox : Box * Space -> Space
insertBox( b, s) == insertbox_aux( b, 100, s)
pre b.width <= freeSpace( s );


removeBox : Box * Space -> Space
removeBox (b, s) == cata[Space](
        nil,
        lambda x : Box & if x.info = b.info then nil else x,
        lambda x : Space, y : Space & mk_BoxSplit(x,y)) (s); 

defragment : Space -> Space 
defragment (s) == cata[Space](
        nil, 
        lambda x: Box & x,
        lambda x : Space, y : Space & 
                if x = nil and y = nil
                then nil
                else  mk_BoxSplit(x,y)) (s)



Theme by Vikram Singh | Powered by WebSVN v2.3.3