Мне нужно проверить, допускает ли автомат слово, которое состоит из одинаковых символов. Если хотя бы одно такое есть, то нужно вывести его, если нет - вывести "NO". Для каждого символа из входного алфавита мы запускаем поиск, и если мы пришли в финальный стан, то должны вывести это слово. Если мы дважды попали не в финальный стан, то прекратить поиск для конкретной буквы(попали в цикл). Я написал часть кода, создал тип автомат, но не знаю как реализовать сам алгоритм на haskell.
main = do {
print(goal m1);
print(goal m2);
print(goal m3);
print(goal m4);
}
w = "abab"
type FSM q = ([q], Alphabet, [Transition q], q, [q])
type Alphabet = [Char]
type Transition q = (q, Char, q)
m1 :: FSM Int
m1 = ([0, 1, 2, 3],
['a', 'b'],
[(0, 'a', 1), (1, 'a', 3), (2, 'a', 2),
(0, 'b', 2), (2, 'b', 3), (1, 'b', 1)],
0,
[3]
)
m2 :: FSM Int
m2 = ([0, 1, 2, 3],
['a', 'b'],
[(0, 'a', 1), (1, 'a', 3), (2, 'a', 2),
(0, 'b', 2), (2, 'b', 3), (1, 'b', 1),
(3, 'a', 3), (3, 'b', 3)],
0,
[3]
)
m3 :: FSM Int
m3 = ([0, 1, 2, 3],
['a', 'b'],
[(0, 'a', 1), (1, 'a', 3), (2, 'a', 2),
(0, 'b', 2), (2, 'b', 3), (1, 'b', 1),
(3, 'a', 1), (3, 'b', 3) ],
0,
[3]
)
m4 :: FSM Int
m4 = ([0, 1, 2, 3, 4, 5],
['a', 'b'],
[(0, 'a', 1), (1, 'a', 2), (2, 'a', 3),
(3, 'a', 5), (5, 'a', 4), (1, 'b', 1),
(3, 'b', 1), (3, 'b', 3) ],
0,
[4]
)
states :: FSM q -> [q]
states (u, _, _, _, _) = u
alph :: FSM q -> Alphabet
alph (_, a, _, _, _) = a
trans :: FSM q -> [Transition q]
trans (_, _, t, _, _) = t
start :: FSM q -> q
start (_, _, _, s, _) = s
final :: FSM q -> [q]
final (_, _, _, _, f) = f
delta :: FSM Int -> Int -> Char -> Int
delta m st symbol | length [q1 | (q0, x, q1) <- trans m, q0 == st, x == symbol] > 0 = [q1 | (q0, x, q1) <- trans m, q0 == st, x == symbol] !! 0 | otherwise = -1
goal:: FSM Int -> String
goal m = seek m (alph m) where
seek m [] = "No"
seek m (x:xs) | find_letter m x > 0 = create_word x (find_letter m x) [] | otherwise = seek m xs
find_letter:: FSM Int -> Char -> Int
find_letter m s = dfs m s (start m) [start m] 0 where
dfs m s state states count
| (delta m state s) elem states = 0
| (delta m state s) == -1 = 0
| (delta m state s) elem (final m) = count + 1
| otherwise = dfs m s (delta m state s) (states++[delta m state s]) (count+1)
create_word:: Char -> Int -> [Char] -> [Char]
create_word symbol 0 list = list
create_word symbol count list = create_word symbol (count-1) (list++[symbol])


Maybe,asumвозвращает первыйJust(из списка) илиNothing, если таких нет.fromMaybeвозвращает первый аргумент, если второй -Nothing, иначе возвращает содержимое второго. – extrn Mar 23 '21 at 15:23flip replicate x <$> m, применяет функциюflip replicate x, т.е.\y -> replicate y xк содержимомуm, если оно есть. иначе ничего не делает. т.е.flip replicate 'x' <$> Just 5=Just (replicate 5 'x'),flip replicate 'x' <$> Nothing=Nothing– extrn Mar 23 '21 at 15:35Just– extrn Mar 23 '21 at 16:40