Он не использует CPS ... но я работаю над библиотекой плоских графов для Haskell, используя схему, аналогичную описанной выше. Края добавляются путем указания того, какое существующее ребро находится до или после него.
Реальная реализация графа завершена, осталось только заставить двоичную сериализацию работать и работать (используя PLANAR_CODE для начинающих, может быть, Graph6 и Sparse6) и некоторые другие дополнительные вещи.
В настоящее время вы получаете двойной граф (который, кажется, вы также нарисовали) с отдельной функцией, хотя я рассматриваю возможность вычисления двойного графика каждый раз, когда вы добавляете ребро (при условии связного графа).
Код можно получить из darcs get <a href="http://code.haskell.org/~ivanm/planar-graph/" rel="nofollow">http://code.haskell.org/~ivanm/planar-graph/</a>
; пример использования (для этого я и разрабатываю эту библиотеку): http://code.haskell.org/~ivanm/dangd/
.
Взято из документации Хэддока в качестве примера его использования:
Например, пусть g
относится к следующему графику (где
n1
и т. Д. Являются метками и именами переменных):
==== ====
( n1 ) ( n2 )
==== ====
====
( n3 )
====
Мы можем добавить ребро между n1
и n2
(используя Anywhere в качестве
EdgePos , поскольку в настоящее время ни на одном узле нет ребер):
((e1,e2),g') = addEdge n1 Anywhere n2 Anywhere "e1" "e2" g
Это приведет к следующему графику:
e2
==== <--------------- ====
( n1 ) ( n2 )
==== ---------------> ====
e1
====
( n3 )
====
Если мы хотим добавить ребра между n2
и n3
, у нас есть три
варианты расположения на n2
:
Использовать Anywhere
: поскольку есть только один другой край, он не делает
Разница с точки зрения внедрения, где идет второй край.
Положите новый край BeforeEdge e2
(по часовой стрелке вокруг n2
).
Положите новый край AfterEdge e2
(по часовой стрелке вокруг n2
).
Поскольку n2
в настоящее время имеет только одно ребро, все три значения EdgePos
приведет к тому же графику, поэтому мы можем произвольно выбрать один:
((e3,e4),g'') = addEdge n2 (BeforeEdge e2) n3 Anywhere "e3" "e4" g'
Тем не менее, с большим количеством ребер нужно позаботиться о том, чтобы EdgePos
значение используется. Полученный график:
e2
==== <--------------- ====
( n1 ) ( n2 )
==== ---------------> ====
e1 | ^
| |
e3 | | e4
| |
v |
====
( n3 )
====
Тот же график (до фактических Edge значений; поэтому он не будет удовлетворять
==
) было бы получено с:
((e4,e3), g'') = addEdge n3 Anywhere n2 (BeforeEdge e2) "e4" "e3" g'