Three wise men argued which of them is the wisest. To find out the truth, everyone put a random color cap on his head. Every sage sees the colors of the caps of his opponents, but does not see his own. The winner is the one who can determine the color of his cap.There is a certain sequence of reasoning that led our sage to the right answer. We will try to model this reasoning.
It so happened that all three pulled the caps white. A passerby passing by tells them: “a white cap is put on one of you”. After some time, the smartest of the wise men exclaimed: “I have a white cap !!!”.
How did he figure it out?
There are three wise men. Each is wearing a cap, either black or white. Everyone knows the colors of his opponents, but does not know his own.
On the first day, they are told that there is at least one white cap. They think all day and vote at the end of the day independently of each other. They give one of two possible results: “I know my color,” “I don't know my color.”
On the second day, they become acquainted with the "voting results" of each of the opponents. Then they think again all day and vote again at the end of the day.
and so on.
Question. How will each of the sages vote on each of the days under different initial conditions?
data Color = Black | White deriving (Show, Eq) type State = [Color] fullState :: [State] fullState = do c1 <- [Black, White] c2 <- [Black, White] c3 <- [Black, White] return [c1, c2, c3] type StateInfo a = State -> a stateInfoColor :: Int -> StateInfo Color stateInfoColor i state = state !! i stateInfoAnyWhite :: StateInfo Bool stateInfoAnyWhite state = or $ map (\c -> c == White) state
type Knowledge = State -> (State -> Bool) knowledgeAbout :: (Eq a) => StateInfo a -> Knowledge knowledgeAbout stateInfo state = let info = stateInfo state in \s -> stateInfo s == info knowledgeIsTrue :: StateInfo Bool -> Knowledge knowledgeIsTrue si _ state = si state knowledgeAboutColor1 :: Knowledge knowledgeAboutColor1 = knowledgeAbout $ stateInfoColor 0 knowledgeAboutColor2 :: Knowledge knowledgeAboutColor2 = knowledgeAbout $ stateInfoColor 1 knowledgeAboutColor3 :: Knowledge knowledgeAboutColor3 = knowledgeAbout $ stateInfoColor 2
= + + ,
= +
knowledgeAnd :: [Knowledge] -> Knowledge knowledgeAnd list stateTrue = \s -> and $ map (\f -> f stateTrue s) list stateInfoList :: [StateInfo a] -> StateInfo [a] stateInfoList sil state = map (\si-> si state) sil knowledgeImply :: Knowledge -> Knowledge -> StateInfo Bool knowledgeImply knowledge1 knowledge2 state = and $ map (\(b1, b2) -> not $ and [b1, not b2]) $ map (\s -> (knowledge1 state s, knowledge2 state s)) fullState
type KnowledgeList = [(Knowledge, Knowledge)] insightList :: KnowledgeList -> StateInfo [Bool] insightList knowledgeList = stateInfoList $ map knowledgeInsight knowledgeList knowledgeInsight :: (Knowledge, Knowledge) -> StateInfo Bool knowledgeInsight (currentKnowledge, targetKnowledge) = knowledgeImply currentKnowledge targetKnowledge manStart_1 = knowledgeAnd [knowledgeAboutColor2, knowledgeAboutColor3, knowledgeAbout stateInfoAnyWhite] manStart_2 = knowledgeAnd [knowledgeAboutColor1, knowledgeAboutColor3, knowledgeAbout stateInfoAnyWhite] manStart_3 = knowledgeAnd [knowledgeAboutColor1, knowledgeAboutColor2, knowledgeAbout stateInfoAnyWhite] knowledgeList_1 :: KnowledgeList knowledgeList_1 = [(manStart_1, knowledgeAboutColor1), (manStart_2, knowledgeAboutColor2), (manStart_3, knowledgeAboutColor3)] insightList_1 :: StateInfo [Bool] insightList_1 = insightList knowledgeList_1
addNewKnowledge :: Knowledge -> KnowledgeList -> KnowledgeList addNewKnowledge newKnowledge knowledgeList = flip map knowledgeList $ \(oldKnowledge, targetKnowledge) -> (knowledgeAnd [oldKnowledge, newKnowledge], targetKnowledge) knowledgeList_2 :: KnowledgeList knowledgeList_2 = addNewKnowledge (knowledgeAbout insightList_1) knowledgeList_1 insightList_2 :: StateInfo [Bool] insightList_2 = insightList knowledgeList_2 knowledgeList_3 :: KnowledgeList knowledgeList_3 = addNewKnowledge (knowledgeAbout insightList_2) knowledgeList_2 insightList_3 :: StateInfo [Bool] insightList_3 = insightList knowledgeList_3
startState = [White, White, White] main = do putStr $ "day 1 result: " ++ (show $ insightList_1 startState) ++ "\n" putStr $ "day 2 result: " ++ (show $ insightList_2 startState) ++ "\n" putStr $ "day 3 result: " ++ (show $ insightList_3 startState) ++ "\n"
startState = [White, White, White] {- result: day 1 result: [False,False,False] day 2 result: [False,False,False] day 3 result: [True,True,True] -}
startState = [Black, White, White] {- result: day 1 result: [False,False,False] day 2 result: [False,True,True] day 3 result: [True,True,True] -}
startState = [Black, Black, White] {- result: day 1 result: [False,False,True] day 2 result: [True,True,True] day 3 result: [True,True,True] -}
data Color = Black | White deriving (Show, Eq) type State = [Color] fullState :: [State] fullState = do c1 <- [Black, White] c2 <- [Black, White] c3 <- [Black, White] return [c1, c2, c3] type StateInfo a = State -> a stateInfoColor :: Int -> StateInfo Color stateInfoColor i state = state !! i stateInfoAnyWhite :: StateInfo Bool stateInfoAnyWhite state = or $ map (\c -> c == White) state -- =================== type Knowledge = State -> (State -> Bool) knowledgeAbout :: (Eq a) => StateInfo a -> Knowledge knowledgeAbout stateInfo state = let info = stateInfo state in \s -> stateInfo s == info knowledgeIsTrue :: StateInfo Bool -> Knowledge knowledgeIsTrue si _ state = si state knowledgeAboutColor1 :: Knowledge knowledgeAboutColor1 = knowledgeAbout $ stateInfoColor 0 knowledgeAboutColor2 :: Knowledge knowledgeAboutColor2 = knowledgeAbout $ stateInfoColor 1 knowledgeAboutColor3 :: Knowledge knowledgeAboutColor3 = knowledgeAbout $ stateInfoColor 2 -- =================== knowledgeAnd :: [Knowledge] -> Knowledge knowledgeAnd list stateTrue = \s -> and $ map (\f -> f stateTrue s) list stateInfoList :: [StateInfo a] -> StateInfo [a] stateInfoList sil state = map (\si-> si state) sil knowledgeImply :: Knowledge -> Knowledge -> StateInfo Bool knowledgeImply knowledge1 knowledge2 state = and $ map (\(b1, b2) -> not $ and [b1, not b2]) $ map (\s -> (knowledge1 state s, knowledge2 state s)) fullState -- ================== type KnowledgeList = [(Knowledge, Knowledge)] insightList :: KnowledgeList -> StateInfo [Bool] insightList knowledgeList = stateInfoList $ map knowledgeInsight knowledgeList knowledgeInsight :: (Knowledge, Knowledge) -> StateInfo Bool knowledgeInsight (currentKnowledge, targetKnowledge) = knowledgeImply currentKnowledge targetKnowledge manStart_1 = knowledgeAnd [knowledgeAboutColor2, knowledgeAboutColor3, knowledgeAbout stateInfoAnyWhite] manStart_2 = knowledgeAnd [knowledgeAboutColor1, knowledgeAboutColor3, knowledgeAbout stateInfoAnyWhite] manStart_3 = knowledgeAnd [knowledgeAboutColor1, knowledgeAboutColor2, knowledgeAbout stateInfoAnyWhite] knowledgeList_1 :: KnowledgeList knowledgeList_1 = [(manStart_1, knowledgeAboutColor1), (manStart_2, knowledgeAboutColor2), (manStart_3, knowledgeAboutColor3)] insightList_1 :: StateInfo [Bool] insightList_1 = insightList knowledgeList_1 -- =============== addNewKnowledge :: Knowledge -> KnowledgeList -> KnowledgeList addNewKnowledge newKnowledge knowledgeList = flip map knowledgeList $ \(oldKnowledge, targetKnowledge) -> (knowledgeAnd [oldKnowledge, newKnowledge], targetKnowledge) knowledgeList_2 :: KnowledgeList knowledgeList_2 = addNewKnowledge (knowledgeAbout insightList_1) knowledgeList_1 insightList_2 :: StateInfo [Bool] insightList_2 = insightList knowledgeList_2 knowledgeList_3 :: KnowledgeList knowledgeList_3 = addNewKnowledge (knowledgeAbout insightList_2) knowledgeList_2 insightList_3 :: StateInfo [Bool] insightList_3 = insightList knowledgeList_3 -- ============= startState = [White, White, White] main = do putStr $ "day 1 result: " ++ (show $ insightList_1 startState) ++ "\n" putStr $ "day 2 result: " ++ (show $ insightList_2 startState) ++ "\n" putStr $ "day 3 result: " ++ (show $ insightList_3 startState) ++ "\n"
Source: https://habr.com/ru/post/349558/