module Logic.Language.Impl.M where import Logic.Language (Language(..), ConcatShowList(..)) import Logic.Language.Derivation (Derivation(..)) -- The MIU system -- (from "Gödel, Escher, Bach: An Eternal Golden Braid" by Douglas Hofstadter) data AlphaMIU = M | I | U deriving (Eq, Show) type StringMIU = [AlphaMIU] instance Language AlphaMIU where isWellFormed (M:_) = True isWellFormed _ = False axiom0 = [[M, I]] infer1 = [ mRule1 , mRule2 , mRule3 , mRule4 ] -- RULE I: If you possess a string whose last letter is I, you can add on a U at the end. mRule1 :: StringMIU -> [StringMIU] mRule1 [I] = [[I, U]] mRule1 (x:xs) = (x:) <$> mRule1 xs mRule1 _ = [] -- RULE II: Suppose you have Mx. Then you may add Mxx to your collection. mRule2 :: StringMIU -> [StringMIU] mRule2 string@(M:xs) = [string ++ xs] mRule2 _ = [] -- RULE III: If III occurs in one of the strings in your collection, you may -- make a new string with U in place of III. mRule3 :: StringMIU -> [StringMIU] mRule3 string@(M:xs) = (M:) <$> aux xs where aux (x@I:xs@(I:I:xs')) = (U:xs'):((x:) <$> aux xs) aux (x:xs) = (x:) <$> aux xs aux _ = [] mRule3 _ = [] -- RULE IV: If UU occurs inside one of your strings, you can drop it. mRule4 :: StringMIU -> [StringMIU] mRule4 string@(M:xs) = (M:) <$> aux xs where aux (x@U:xs@(U:xs')) = xs':((x:) <$> aux xs) aux (x:xs) = (x:) <$> aux xs aux _ = [] mRule4 _ = [] {- ghci> map ConcatShowList infer0 :: [ConcatShowList AlphaMIU] [MI] ghci> map ConcatShowList $ concat $ map ($ [M, I, I, I, I, U, U, I]) infer1 [MIIIIUUIU,MIIIIUUIIIIIUUI,MUIUUI,MIUUUI,MIIIII] -} deriveMIIUII :: Derivation AlphaMIU deriveMIIUII = Infer1 3 0 $ Infer1 2 2 $ Infer1 0 0 $ Infer1 3 0 $ Infer1 3 0 $ Infer1 2 2 $ Infer1 1 0 $ Infer1 2 5 $ Infer1 0 0 $ Infer1 1 0 $ Infer1 1 0 $ Infer1 1 0 $ Axiom0 0 {- ghci> import Logic.Language.Derivation (resolveDerivation) ghci> resolveDerivation deriveMIIUII Right [M,I,I,U,I,I] -}