notDefTypes :: [String] -> [String]
notDefTypes xs = removeDuplicates notDefinedTypes
                  where notDefinedTypes = concat (map defTypes separated)
                        separated = map (\x -> split_str x "") xs
                        
                        split_str :: String -> String -> [String]
                        split_str [] saved = [saved]
                        split_str (x:xs) saved
                          | x == ' ' = saved:(split_str xs "")
                          |otherwise = split_str xs (saved++[x])

                        defTypes :: [String] -> [String]
                        defTypes [] = []
                        defTypes (x:[])
                          | (definedBaseTypes x) = []
                          | otherwise = [x]
                        defTypes (x:xs) = (keepUndefinedComplex x (length xs))++(keepUndefinedSimples xs)

                        keepUndefinedComplex :: String -> Int -> [String]
                        keepUndefinedComplex x n
                          | (definedComplexTypes x) = []
                          | otherwise = [x ++ " " ++(listOfVariables n)]

                        listOfVariables :: Int -> String
                        listOfVariables 0 = ""
                        listOfVariables 1 = "x1"
                        listOfVariables n = ("x"++(show n)) ++ " " ++ (listOfVariables (n-1))
                        
                        keepUndefinedSimples :: [String] -> [String]
                        keepUndefinedSimples [] = []
                        keepUndefinedSimples (x:xs)
                          | (definedBaseTypes x) = keepUndefinedSimples xs
                          | otherwise = x:(keepUndefinedSimples xs)
notDefTypes :: [String] -> [String]
notDefTypes xs = removeDuplicates notDefinedTypes
                  where notDefinedTypes = concat (map defTypes separated)
                        separated = map (\x -> split_str x "") xs
                        
                        split_str :: String -> String -> [String]
                        split_str [] saved = [saved]
                        split_str (x:xs) saved
                          | x == ' ' = saved:(split_str xs "")
                          |otherwise = split_str xs (saved++[x])

                        defTypes :: [String] -> [String]
                        defTypes [] = []
                        defTypes (x:[])
                          | (definedBaseTypes x) = []
                          | otherwise = [x]
                        defTypes (x:xs) = (keepUndefinedComplex x (length xs))++(keepUndefinedSimples xs)

                        keepUndefinedComplex :: String -> Int -> [String]
                        keepUndefinedComplex x n
                          | (definedComplexTypes x) = []
                          | otherwise = [x ++ " " ++(listOfVariables n)]

                        listOfVariables :: Int -> String
                        listOfVariables 0 = ""
                        listOfVariables 1 = "x1"
                        listOfVariables n = ("x"++(show n)) ++ " " ++ (listOfVariables (n-1))
                        
                        keepUndefinedSimples :: [String] -> [String]
                        keepUndefinedSimples [] = []
                        keepUndefinedSimples (x:xs)
                          | (definedBaseTypes x) = keepUndefinedSimples xs
                          | otherwise = x:(keepUndefinedSimples xs)
notDefTypes xs = removeDuplicates notDefinedTypes
                  where notDefinedTypes = concat (map defTypes separated)
                        separated = map (\x -> split_str x "") xs
                        
                        split_str :: String -> String -> [String]
                        split_str [] saved = [saved]
                        split_str (x:xs) saved
                          | x == ' ' = saved:(split_str xs "")
                          |otherwise = split_str xs (saved++[x])

                        defTypes :: [String] -> [String]
                        defTypes [] = []
                        defTypes (x:[])
                          | (definedBaseTypes x) = []
                          | otherwise = [x]
                        defTypes (x:xs) = (keepUndefinedComplex x (length xs))++(keepUndefinedSimples xs)

                        keepUndefinedComplex :: String -> Int -> [String]
                        keepUndefinedComplex x n
                          | (definedComplexTypes x) = []
                          | otherwise = [x ++ " " ++(listOfVariables n)]

                        listOfVariables :: Int -> String
                        listOfVariables 0 = ""
                        listOfVariables 1 = "x1"
                        listOfVariables n = ("x"++(show n)) ++ " " ++ (listOfVariables (n-1))
                        
                        keepUndefinedSimples :: [String] -> [String]
                        keepUndefinedSimples [] = []
                        keepUndefinedSimples (x:xs)
                          | (definedBaseTypes x) = keepUndefinedSimples xs
                          | otherwise = x:(keepUndefinedSimples xs)