1 module Memo(Triangle,mkmemo,lazyAbove) where 2 import Numbers 3 import Vectors 4 import EdgePlate 5 import Comparing(above) 6 import Ix 7 import Array 8 9 data Triangle a = a :^ a deriving (Eq,Ord, {-1.3-}Show) 10 11 instance (Enum a,Ord a,Ix a) => Ix (Triangle a) where 12 range (t0 :^ b0 , t1 :^ b1) = 13 [t :^ b | t <- [t0 .. t1] 14 , b <- take (1+index(t0,t1) t) [b0 .. ] 15 , t :^ b <= t1 :^ b1 16 ] 17 index (t0 :^ b0 , t1 :^ b1) (t :^ b) = 18 ti * (ti+1) `div` 2 + index (b0,b1) b 19 where ti = index (t0,t1) t 20 inRange (t0 :^ b0 , t1 :^ b1) (t :^ b) = 21 inRange (t0,t1) t && 22 inRange (b0,b1) b && index (t0,t1) t >= index (b0,b1) b 23 24 mkmemo :: (Plate -> Plate -> a) -> Object -> Array (Triangle Int) a 25 mkmemo f obj = 26 array (2:^1 , len:^(len-1)) [((top:^bottom) , f ls ks) 27 |ls@(Plt top _) <- obj 28 ,ks@(Plt bottom _) <- obj 29 ,top > bottom] 30 where len = length obj 31 32 33 lazyAbove :: Array (Triangle Int) Bool -> Plate -> Plate -> Bool 34 lazyAbove memory top@(Plt n _) bottom@(Plt m _) 35 | inRange (bounds memory) (n :^ m) = memory ! (n:^m) 36 | n==m = False 37 | otherwise = if memory ! (m:^n) 38 then False 39 else top`above`bottom