Интерференция в клеточном автомате. Причины неудачи

Sep 16, 2018 08:18


В очередной раз потерпел фиаско, пытаясь смоделировать интерференцию с помощью клеточного автомата. Но в этот раз стала понятна причина. Пытаясь понять почему, я построил дерево, показывающае вклад каждой ячейки в каждую через n шагов:

data Expr a = At !Index  | PlusMul [(a, Expr a)]

Cтрою его с помощью следующего шага:

step = do cur <- at

left <- atLeft

right <- atRight

return $ PlusMul [((1/3), cur), ((1/3), left), ((1/3), right)]

step это контекстная функция (читалка) которая строится из примитивных читалок at, atLeft, atRight. Она принимает текущий контекст (тек позицию и ее значение,  значение соседей) и возвращает новое значение для текущей позиции. (Другими словами это т.н. reader монада).

Применяя этот шаг ко всем ячейкам многократно, мы тем самым строим деревья. Например, чтобы применить два раза ко всем ячейкам я делаю это следующим образом:

initial `coBindZ` step `coBindZ` step

(initial тут изначальный контект состоящих из ...,At -1 At 0, At 1,... а название coBind как бы должно нам намекать что контекст это комонада)

В принципе, этого можно было и не делать, так как, взглянув на структуру дерева и то как оно строится уже становится понятна причина неудачи. Дело в том что, несмотря на то что одни ячейки могут встречаться в дереве чаще других, любой отдельный путь до любой ячейки в дереве равнозначный и одинаковой длины.Если бы мы хотели чтобы какие-то пути с помощью фаз взаимогасились, то нам нужны были бы разные фазы. А здесь разнице фаз просто неоткуда взятся ввиду равнозначности всех путей.



Таким образом, мы должны будем ввести неравнозначность между переходами из соседних клеток по отношению к переходу ячейки в саму себя. Например, делая этот переход без изменения фаз. Но это я попробую уже в следующий раз.

Previous post Next post
Up