å»å¹Žã®å€ã«åå ããã®ã§ããã
Google Summer of Code 2019 ã®åå è
ãšããŠãã©ã€ãã©ãªå
ã§ãããžã§ã¯ããå®è¡ããŸãã
ãã®æçš¿ã§ã¯ãHaskell ã§ã°ã©ãã®äºéšæ§ããã§ãã¯ããã¢ã«ãŽãªãºã ã®å®è£ ã«ã€ããŠèª¬æããŸãã ãã®ã¢ã«ãŽãªãºã ã¯æãåºæ¬çãªãã®ã® XNUMX ã€ã§ããããããé¢æ°åã¹ã¿ã€ã«ã§çŸããå®è£ ããã«ã¯æ°åã®å埩ãå¿ èŠã§ãããªãã®äœæ¥ãå¿ èŠã§ããã ãã®çµæãã¢ãããã©ã³ã¹ãã©ãŒããŒã䜿çšããå®è£ ã«èœã¡çããŸããã
ç§ã«ã€ããŠ
ç§ã®ååã¯ãŽã¡ã·ãªãŒã»ã¢ã«ãã§ããããµã³ã¯ãããã«ãã«ã¯å€§åŠã® XNUMX 幎çã§ãã 以åæžããããã°ã§
ã¢ã«ãŽãªãºã ã®å®è£ ã«ã€ããŠ
åºæ
ããã°ã©ã ã«åå ããåŠçã«ã¯ããã°ãæžãããšã匷ãæšå¥šãããŸãã 圌ãã¯ç§ã«ããã°ã®ãã©ãããã©ãŒã ãæäŸããŠãããŸãã
åé¡ã®ã³ãŒããå«ããã«ãªã¯ãšã¹ããèŠã€ãããŸã
ç§ã®ä»äºã®çµæã«ã€ããŠèªãããšãã§ããŸãïŒè±èªïŒ
ãã®æçš¿ã§ã¯ãèªè ãé¢æ°åããã°ã©ãã³ã°ã®åºæ¬æŠå¿µã«ç²ŸéããŠããããšãåæãšããŠããŸãããå¿ èŠãªãšãã«äœ¿çšãããŠãããã¹ãŠã®çšèªãæãåºãããã«åªããŸãã
ã°ã©ãã®äºéšæ§ã®ãã§ãã¯
ã°ã©ãã®äºéšæ§ããã§ãã¯ããã¢ã«ãŽãªãºã ã¯ãéåžžãæãåçŽãªã°ã©ã ã¢ã«ãŽãªãºã ã® XNUMX ã€ãšããŠã¢ã«ãŽãªãºã ã®ã³ãŒã¹ã§èª¬æãããŸãã 圌ã®ã¢ã€ãã¢ã¯åçŽã§ãããŸããäœããã®æ¹æ³ã§é ç¹ãå·ŠåŽãŸãã¯å³åŽã®å ±æã«é 眮ããççŸãããšããžãèŠã€ãã£ãå Žåãã°ã©ãã XNUMX éšæ§æã§ã¯ãªããšäž»åŒµããŸãã
ããå°ã詳ãã説æãããšããŸãå·ŠåŽã®å ±æã«é ç¹ãé 眮ããŸãã æããã«ããã®é ç¹ã®é£æ¥ããé ç¹ã¯ãã¹ãŠå³ããŒãã«ååšããå¿ èŠããããŸãã ããã«ããã®é ç¹ã®é£æ¥é ç¹ã®ãã¹ãŠã®é£æ¥é ç¹ã¯å·ŠããŒãã«ååšããå¿ èŠãããã以äžåæ§ã«ãªããŸãã éå§ããé ç¹ã®æ¥ç¶ã³ã³ããŒãã³ãå ã«é£æ¥ãå²ãåœãŠãŠããªãé ç¹ããŸã ååšããéããé ç¹ãžã®å ±æã®å²ãåœãŠãç¶ããŸãã 次ã«ãæ¥ç¶ãããŠãããã¹ãŠã®ã³ã³ããŒãã³ãã«å¯ŸããŠãã®ã¢ã¯ã·ã§ã³ãç¹°ãè¿ããŸãã
åãããŒãã£ã·ã§ã³ã«å±ããé ç¹éã«ãšããžãããå Žåãã°ã©ãå ã§å¥æ°ã®ãµã€ã¯ã«ãèŠã€ããã®ã¯é£ãããããŸãããããã㯠XNUMX éšã°ã©ãã§ã¯äžå¯èœã§ããããšãåºãç¥ãããŠããŸã (ãããŠéåžžã«æçœã§ã)ã ãã以å€ã®å Žåã¯ãæ£ããããŒãã£ã·ã§ã³ãåŸãããŸããããã¯ãã°ã©ãã XNUMX éšã§ããããšãæå³ããŸãã
éåžžããã®ã¢ã«ãŽãªãºã ã¯æ¬¡ã䜿çšããŠå®è£
ãããŸãã
ããã§ã次ã®ãããªã¹ããŒã ã«ãã©ãçããŸããã æ·±ãåªå æ€çŽ¢ã䜿çšããŠã°ã©ãã®é ç¹ã暪æãããããã«ã·ã§ã¢ãå²ãåœãŠããšããžã«æ²¿ã£ãŠç§»åããã«ã€ããŠã·ã§ã¢ã®æ°ãå€æŽããŸãã ãã§ã«å ±æãå²ãåœãŠãããŠããé ç¹ã«å ±æãå²ãåœãŠãããšãããšããã®ã°ã©ã㯠XNUMX éšæ§æã§ã¯ãªããšå®å šã«èšããŸãã ãã¹ãŠã®é ç¹ã«å ±æãå²ãåœãŠããããã¹ãŠã®ãšããžã確èªãããæç¹ã§ãé©åãªããŒãã£ã·ã§ã³ãåŸãããŸãã
èšç®ã®çŽåºŠ
Haskell ã§ã¯ããã¹ãŠã®èšç®ã次ã®ããã«è¡ããããšä»®å®ããŸãã ãããã§ãã ãããããããæ¬åœã«äºå®ã§ããã°ãç»é¢ã«äœãåºåããããšãã§ããªããªããŸãã ãŸã£ããã ããã㪠èšç®ãæ æ°ãããŠèšç®ãäžã€ããããŸãã æé€ äœããèšç®ããçç±ã ããã°ã©ã å ã§è¡ããããã¹ãŠã®èšç®ã¯äœããã®æ¹æ³ã§åŒ·å¶çã«å®è¡ãããŸãã ãäžæœã ã¢ããIOã
ã¢ããã¯èšç®ãè¡šçŸããæ¹æ³ã§ãã å¹æ ãã¹ã±ã«ã§ã ããããã©ã®ããã«æ©èœãããã«ã€ããŠã®èª¬æã¯ããã®æçš¿ã®ç¯å²ãè¶
ããŠããŸãã é©åã§æ確ãªèª¬æã¯è±èªã§èªãããšãã§ããŸã
ããã§ææããŠããããã®ã¯ãIO ãªã©ã®äžéšã®ã¢ããã¯ã³ã³ãã€ã©ã®éæ³ã«ãã£ãŠå®è£ ãããŠãããããã®ä»ã®ã»ãšãã©ãã¹ãŠã®ã¢ããã¯ãœãããŠã§ã¢ã§å®è£ ãããŠããããããã®èšç®ã¯ãã¹ãŠçŽç²ã§ãããšããããšã§ãã
ãšãã§ã¯ãã¯ãããããããããããã«ç¬èªã®ã¢ããããããŸãã ããã¯éåžžã«åŒ·åã§çŸããçè«ã§ãããã¹ãŠã®ã¢ããã¯åãã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ããŸãã 次㮠XNUMX ã€ã®ã¢ããã«ã€ããŠèª¬æããŸãã
- ea ã¯ãa åã®å€ãè¿ãèšç®ããe åã®äŸå€ãã¹ããŒããèšç®ã§ãã ãã®ã¢ããã®åäœã¯åœä»€åèšèªã®äŸå€åŠçã«éåžžã«äŒŒãŠããããšã©ãŒã¯ææãŸãã¯æž¡ãããŸãã äž»ãªéãã¯ãåœä»€åèšèªã¯éåžžãªãã¬ãŒãã£ã³ã° ã·ã¹ãã ã®ã¡ã«ããºã ã䜿çšããã®ã«å¯Ÿããã¢ãã㯠Haskell ã®æšæºã©ã€ãã©ãªã«å®å šã«è«ççã«å®è£ ãããããšã§ãã
- ç¶æ sa ã¯ãå a ã®å€ãè¿ããå s ã®å¯å€ç¶æ ã«ã¢ã¯ã»ã¹ããèšç®ã§ãã
- ãã¶ãã might ã¢ããã¯ãNothing ãè¿ãããšã§ãã€ã§ãäžæã§ããèšç®ãè¡šããŸãã ãã ããMaybe åã® MonadPlus ã¯ã©ã¹ã®å®è£ ã«ã€ããŠèª¬æããŸããããã¯éã®å¹æãè¡šããŸããããã¯ãç¹å®ã®å€ãè¿ãããšã§ãã€ã§ãäžæã§ããèšç®ã§ãã
ã¢ã«ãŽãªãºã ã®å®è£
Graph a ãš Bigraph ab ãšãã XNUMX ã€ã®ããŒã¿ ã¿ã€ãããããXNUMX ã€ç®ã¯ã¿ã€ã a ã®å€ã§ã©ãã«ä»ããããé ç¹ãæã€ã°ã©ããè¡šããXNUMX ã€ç®ã¯ã¿ã€ã a ã®å€ã§ã©ãã«ä»ããããé ç¹ãšå³åŽã®é ç¹ãæ〠XNUMX éšã°ã©ããè¡šããŸãã -ã¿ã€ã b ã®å€ã§ã©ãã«ä»ããããåŽã®é ç¹ã
ããã㯠Alga ã©ã€ãã©ãªã®ã¿ã€ãã§ã¯ãããŸããã Alga ã«ã¯ãç¡åäºéšã°ã©ãã®è¡šçŸããããŸããã ããããããããããã«ãã®ãããªã¿ã€ããäœæããŸããã
次ã®ã·ã°ããã£ãæã€ãã«ããŒé¢æ°ãå¿ èŠã«ãªããŸãã
-- СпОÑПк ÑПÑеЎей ЎаММПй веÑÑОМÑ.
neighbours :: Ord a => a -> Graph a -> [a]
-- ÐПÑÑÑПОÑÑ ÐŽÐ²ÑЎПлÑÐœÑй гÑÐ°Ñ Ð¿ÐŸ гÑаÑÑ Ðž ÑÑМкÑОО, ÐŽÐ»Ñ ÐºÐ°Ð¶ÐŽÐŸÐ¹ веÑÑОМÑ
-- вÑЎаÑÑей ÐµÑ ÐŽÐŸÐ»Ñ Ðž пПЌеÑÐºÑ Ð² МПвПй ЎПле, ОгМПÑОÑÑÑ ÐºÐŸÐœÑлОкÑÐœÑе ÑÑбÑа.
toBipartiteWith :: (Ord a, Ord b, Ord c) => (a -> Either b c)
-> Graph a
-> Bigraph b c
-- СпОÑПк веÑÑОМ в гÑаÑе
vertexList :: Ord a => Graph a -> [a]
СОгМаÑÑÑа ÑÑМкÑОО, кПÑПÑÑÑ ÐŒÑ Ð±ÑЎеЌ пОÑаÑÑ, вÑглÑÐŽÐžÑ Ñак:
type OddCycle a = [a]
detectParts :: Ord a => Graph a -> Either (OddCycle a) (Bigraph a a)
æ·±ãåªå æ€çŽ¢äžã«ç«¶åãããšããžãèŠã€ãã£ãå Žåãå¥æ°ã®ãµã€ã¯ã«ãååž°ã¹ã¿ãã¯ã®æäžéšã«ããããšãç°¡åã«ããããŸãã ãããã£ãŠãããã埩å ããã«ã¯ãååž°ã¹ã¿ãã¯ããæåã«åºçŸããæåŸã®é ç¹ãŸã§ãã¹ãŠãåæããå¿ èŠããããŸãã
åé ç¹ã®å ±æçªå·ã®é£æ³é åãç¶æããããšã«ãããæ·±ãåªå æ€çŽ¢ãå®è£ ããŸãã ååž°ã¹ã¿ãã¯ã¯ãéžæããã¢ããã® Functor ã¯ã©ã¹ã®å®è£ ãéããŠèªåçã«ç¶æãããŸããå¿ èŠãªã®ã¯ããã¹ã®ãã¹ãŠã®é ç¹ãååž°é¢æ°ããè¿ãããçµæã«å ¥ããããšã ãã§ãã
ç§ã®æåã®ã¢ã€ãã¢ã¯ãå¿ èŠãªå¹æãæ£ç¢ºã«å®è£ ããŠãããšæããããEither ã¢ããã䜿çšããããšã§ããã ç§ãæåã«æžããå®è£ ã¯ããã®ãªãã·ã§ã³ã«éåžžã«è¿ããã®ã§ããã å®éãç§ã¯ããæç¹ã§ XNUMX ã€ã®ç°ãªãå®è£ ãèããŸããããæçµçã«ã¯å¥ã®å®è£ ã«èœã¡çããŸããã
ãŸããå
±æèå¥åã®é£æ³é
åãç¶æããå¿
èŠããããŸããããã¯ç¶æ
ã«é¢ãããã®ã§ãã 次ã«ã競åãæ€åºããããšãã«åæ¢ã§ããå¿
èŠããããŸãã ããã¯ãEither ã® Monad ããMaybe ã® MonadPlus ã®ããããã«ãªããŸãã äž»ãªéãã¯ãã©ã¡ããèšç®ãåæ¢ããŠããªãå Žåã«å€ãè¿ãããšãã§ããã®ã«å¯ŸããMaybe ã¯ãã®å Žåãããã«é¢ããæ
å ±ã®ã¿ãè¿ãããšã§ãã æåãè¡šãå¥ã®å€ã¯å¿
èŠãªã (å€ã¯æ¢ã« State ã«ä¿åãããŠãã) ãããMaybe ãéžæããŸãã ãããŠãXNUMX ã€ã®ã¢ããã®å¹æãçµã¿åãããå¿
èŠãããç¬éã«ããããã¯åºãŠããŸãã
ãªããã®ãããªè€éãªã¿ã€ããéžæããã®ã§ãããã? çç±ã¯ XNUMX ã€ãããŸãã ãŸããå®è£ ã¯åœä»€åãšéåžžã«äŒŒãŠããããšãããããŸãã 次ã«ãååž°ããæ»ããšãã«ç«¶åãçºçããå Žåã«æ»ãå€ãæäœããŠãå¥åŠãªã«ãŒãã埩å ããå¿ èŠããããŸããããã¯ãMaybe ã¢ããã§è¡ãæ¹ãã¯ããã«ç°¡åã§ãã
ãããã£ãŠããã®å®è£ ãåŸãããŸãã
{-# LANGUAGE ExplicitForAll #-}
{-# LANGUAGE ScopedTypeVariables #-}
data Part = LeftPart | RightPart
otherPart :: Part -> Part
otherPart LeftPart = RightPart
otherPart RightPart = LeftPart
type PartMap a = Map.Map a Part
type OddCycle a = [a]
toEither :: Ord a => PartMap a -> a -> Either a a
toEither m v = case fromJust (v `Map.lookup` m) of
LeftPart -> Left v
RightPart -> Right v
type PartMonad a = MaybeT (State (PartMap a)) [a]
detectParts :: forall a. Ord a => Graph a -> Either (OddCycle a) (Bigraph a a)
detectParts g = case runState (runMaybeT dfs) Map.empty of
(Just c, _) -> Left $ oddCycle c
(Nothing, m) -> Right $ toBipartiteWith (toEither m) g
where
inVertex :: Part -> a -> PartMonad a
inVertex p v = ((:) v) <$> do modify $ Map.insert v p
let q = otherPart p
msum [ onEdge q u | u <- neigbours v g ]
{-# INLINE onEdge #-}
onEdge :: Part -> a -> PartMonad a
onEdge p v = do m <- get
case v `Map.lookup` m of
Nothing -> inVertex p v
Just q -> do guard (q /= p)
return [v]
processVertex :: a -> PartMonad a
processVertex v = do m <- get
guard (v `Map.notMember` m)
inVertex LeftPart v
dfs :: PartMonad a
dfs = msum [ processVertex v | v <- vertexList g ]
oddCycle :: [a] -> [a]
oddCycle c = tail (dropWhile ((/=) last c) c)
where ãããã¯ã¯ã¢ã«ãŽãªãºã ã®äžæ žã§ãã ãã®å éšã§äœãèµ·ãã£ãŠããã®ãã説æããŠã¿ãŸãã
- inVertex ã¯ãåããŠé ç¹ã«ã¢ã¯ã»ã¹ããæ·±ãåªå æ€çŽ¢ã®äžéšã§ãã ããã§ã¯ãé ç¹ã«å ±æçªå·ãå²ãåœãŠããã¹ãŠã®è¿åã«å¯Ÿã㊠onEdge ãå®è¡ããŸãã ããã¯ã³ãŒã« ã¹ã¿ãã¯ã埩å ããå Žæã§ããããŸããmsum ãå€ãè¿ããå Žåã¯ãããã«é ç¹ v ãããã·ã¥ããŸãã
- onEdge ã¯ãšããžã«ã¢ã¯ã»ã¹ããéšåã§ãã ããã¯ãšããžããšã« XNUMX ååŒã³åºãããŸãã ããã§ã¯ãå察åŽã®é ç¹ã蚪åãããŠãããã©ããã確èªãã蚪åãããŠããªãå Žåã¯èšªåããŸãã ã¢ã¯ã»ã¹ãããå Žåã¯ããšããžã競åããŠãããã©ããã確èªããŸãã ããã§ããã°ãååž°ã¹ã¿ãã¯ã®æäžéšã®å€ãè¿ããŸããæ»ãæã«ä»ã®ãã¹ãŠã®é ç¹ãããã«é 眮ãããŸãã
- processVertex ã¯ãåé ç¹ã蚪åãããŠãããã©ããã確èªãã蚪åãããŠããªãå Žå㯠inVertex ãå®è¡ããŸãã
- dfs ã¯ãã¹ãŠã®é ç¹ã§ processVertex ãå®è¡ããŸãã
ããã§å šéšã§ãã
INLINEãšããèšèã®æŽå²
INLINE ãšããåèªã¯ã¢ã«ãŽãªãºã ã®æåã®å®è£ ã«ã¯ååšãããåŸããç»å ŽããŸããã ããè¯ãå®è£ ãèŠã€ããããšãããšãããäžéšã®ã°ã©ãã§ã¯é INLINE ããŒãžã§ã³ã®æ¹ãèããé ãããšãããããŸããã æå³çã«ã¯é¢æ°ã¯åãããã«åäœããã¯ãã§ããããšãèãããšãããã«ã¯éåžžã«é©ããŸããã ããã«å¥åŠãªããšã«ãç°ãªãããŒãžã§ã³ã® GHC ãæèŒããå¥ã®ãã·ã³ã§ã¯ç®ç«ã£ãéãã¯ãããŸããã§ããã
8.4.4 é±éãã㊠GHC ã³ã¢ã®åºåãèªãã åŸã8.6.5ââ è¡ã®æ瀺ç㪠INLINE ã§åé¡ã解決ã§ããŸããã GHC XNUMX ãš GHC XNUMX ã®éã®ããæç¹ã§ããªããã£ãã€ã¶ã¯ãããç¬èªã«è¡ãããšãåæ¢ããŸããã
Haskell ããã°ã©ãã³ã°ã§ãã®ãããªæ±ãã«ééãããšã¯äºæ³ããŠããŸããã§ããã ããããä»ã§ããªããã£ãã€ã¶ãŒã¯æã ééããç¯ãã®ã§ããããã«ãã³ããäžããã®ãç§ãã¡ã®ä»äºã§ãã ããšãã°ãããã§ã¯é¢æ°ãåœä»€åããŒãžã§ã³ã§ã€ã³ã©ã€ã³åãããŠãããããã€ã³ã©ã€ã³åããå¿ èŠãããããšããããããããã³ã³ãã€ã©ã«ãã³ããäžããçç±ã«ãªããŸãã
次ã«äœãèµ·ãããŸãããïŒ
次ã«ãä»ã®ã¢ããã䜿çšã㊠Hopcroft-Karp ã¢ã«ãŽãªãºã ãå®è£ ããããã°ã©ã ã¯çµäºããŸããã
Google Summer of Code ã®ãããã§ãç§ã¯é¢æ°åããã°ã©ãã³ã°ã®å®è·µçãªçµéšãç©ãããšãã§ãããããç¿å¹Žã®å€ã«ãžã§ãŒã³ ã¹ããªãŒãã§ã€ã³ã¿ãŒã³ã·ããã«åå ã§ããã ãã§ãªããããã«ã®ç¥èè±å¯ãªèŽè¡ã®éã§ããã®å Žæãã©ã®çšåºŠç¥ãããŠãããã¯ããããŸããããå€äŒã¿ã«é¢æ°åããã°ã©ãã³ã°ã«åãçµãããšãã§ããæ°å°ãªãå Žæã®äžã€ã§ãïŒã ãã§ãªããäŒçµ±çãªèšèªã§ã®ç§ã®çµéšãšã¯å€§ããç°ãªãããã®ãã©ãã€ã ãå®éã«é©çšããçŽ æŽãããäžçã«ãç§ã玹ä»ããŠãããŸããã
åºæïŒ habr.com