module Memo(Triangle,mkmemo,lazyAbove) where
import Numbers
import Vectors
import EdgePlate
import Comparing(above)
import Ix
import Array
data Triangle a = a :^ a deriving (Eq,Ord, {-1.3-}Show)
instance (Enum a,Ord a,Ix a) => Ix (Triangle a) where
range (t0 :^ b0 , t1 :^ b1) =
[t :^ b | t <- [t0 .. t1]
, b <- take (1+index(t0,t1) t) [b0 .. ]
, t :^ b <= t1 :^ b1
]
index (t0 :^ b0 , t1 :^ b1) (t :^ b) =
ti * (ti+1) `div` 2 + index (b0,b1) b
where ti = index (t0,t1) t
inRange (t0 :^ b0 , t1 :^ b1) (t :^ b) =
inRange (t0,t1) t &&
inRange (b0,b1) b && index (t0,t1) t >= index (b0,b1) b
mkmemo :: (Plate -> Plate -> a) -> Object -> Array (Triangle Int) a
mkmemo f obj =
array (2:^1 , len:^(len-1)) [((top:^bottom) , f ls ks)
|ls@(Plt top _) <- obj
,ks@(Plt bottom _) <- obj
,top > bottom]
where len = length obj
lazyAbove :: Array (Triangle Int) Bool -> Plate -> Plate -> Bool
lazyAbove memory top@(Plt n _) bottom@(Plt m _)
| inRange (bounds memory) (n :^ m) = memory ! (n:^m)
| n==m = False
| otherwise = if memory ! (m:^n)
then False
else top`above`bottom
|