module PGF.SortTop
( forExample
) where
import PGF.CId
import PGF.Data
import qualified Data.Map as Map
import qualified Data.Set as Set
import Data.Maybe
arguments :: Type -> [CId]
arguments (DTyp [] _ _) = []
arguments (DTyp hypos _ _) = [ t | (_,_, DTyp _ t _) <- hypos]
-- topological order of functions
-- in the order that they should be tested and generated in an example-based system
showInOrder :: Abstr -> Set.Set CId -> Set.Set CId -> Set.Set CId -> IO [[((CId,CId),[CId])]]
showInOrder abs fset remset avset =
let mtypes = typesInterm abs fset
nextsetWithArgs = Set.map (\(x,y) -> ((x, returnCat abs x), fromJust y)) $ Set.filter (isJust.snd) $ Set.map (\x -> (x, isArg abs mtypes avset x)) remset
nextset = Set.map (fst.fst) nextsetWithArgs
nextcat = Set.map (returnCat abs) nextset
diffset = Set.difference remset nextset
in
if Set.null diffset then do
return [Set.toList nextsetWithArgs]
else if Set.null nextset then do
putStrLn $ "not comparable : " ++ show diffset
return []
else do
rest <- showInOrder abs (Set.union fset nextset) (Set.difference remset nextset) (Set.union avset nextcat)
return $ (Set.toList nextsetWithArgs) : rest
isArg :: Abstr -> Map.Map CId CId -> Set.Set CId -> CId -> Maybe [CId]
isArg abs mtypes scid cid =
let p = Map.lookup cid $ funs abs
(ty,_,_,_) = fromJust p
args = arguments ty
setargs = Set.fromList args
cond = Set.null $ Set.difference setargs scid
in
if isNothing p then error $ "not found " ++ show cid ++ "here !!"
else if cond then return args
else Nothing
typesInterm :: Abstr -> Set.Set CId -> Map.Map CId CId
typesInterm abs fset =
let fs = funs abs
fsetTypes = Set.map (\x ->
let (DTyp _ c _,_,_,_)=fromJust $ Map.lookup x fs
in (x,c)) fset
in Map.fromList $ Set.toList fsetTypes
{-
takeArgs :: Map.Map CId CId -> Map.Map CId Expr -> CId -> Expr
takeArgs mtypes mexpr ty =
let xarg = head $ Map.keys $ Map.filter (==ty) mtypes
in fromJust $ Map.lookup xarg mexpr
doesReturnCat :: Type -> CId -> Bool
doesReturnCat (DTyp _ c _) cat = c == cat
-}
returnCat :: Abstr -> CId -> CId
returnCat abs cid =
let p = Map.lookup cid $ funs abs
(DTyp _ c _,_,_,_) = fromJust p
in if isNothing p then error $ "not found "++ show cid ++ " in abstract "
else c
-- topological order of the categories
forExample :: PGF -> IO [[((CId,CId),[CId])]]
forExample pgf = let abs = abstract pgf
in showInOrder abs Set.empty (Set.fromList $ Map.keys $ funs abs) Set.empty