Хочу человеческий синтаксис для описания графов.
Что у нас сейчас есть:
Graph description languages.
Половина из них основана на XML, что хорошо для инструментов, но плохо для написания руками.
DOT спроектирован математиками и из-за этого тоже излишне многословен. Мы можем определить в графе дефолтные свойства вершин и рёбер, и это позволяет немного экономить. Но если у нас в графе два типа рёбер, то один можно сделать дефолтным, а второй приходится выписывать каждый раз:
digraph G {
edge [arrowhead=empty] # inheritance
Derived -> Base
Aggregate -> Part [arrowtail=odiamond, arrowhead=open] # aggregation
}
Или можно определить подграф и рёбра второго типа определять в нём, что плохо для локальности (часто хочется описывать рёбра, относящиеся к одной вершине, рядом):
digraph G {
subgraph {
edge [arrowhead=empty] # inheritance
Derived -> Base
}
subgraph {
edge [arrowtail=odiamond, arrowhead=open] # aggregation
Aggregate -> Part
}
}
Как надо:
Есть классы вершин и рёбер. Все общие свойства вершин или рёбер одного класса описываются в определении класса. Важно, что определения классов можно вынести в библиотеки и подключать их, когда надо.
Минимальное определение вершины состоит из имени класса вершины и имени вершины, на отдельной строке, через пробел. Далее опционально индивидуальные свойства вершины. (Тут решить между синтаксисом со скобками и разделителями или просто indentation-based.) Имя может быть одним словом или произвольной строкой в кавычках.
Минимальное определение ребра состоит из имени начальной вершины, имени класса ребра и имени конечной вершины, также на отдельной строке через пробел, также с опциональным блоком свойств.
Пример:
node.class [shape=box]
node.interface [shape=circle]
edge.is-a [arrowhead=empty]
edge.implements [arrowhead=empty, style=dashed]
edge.has-a [arrowtail=odiamond, arrowhead=open]
edge.owns-a [arrowtail=diamond, arrowhead=open]
interface IThing
class Base
class Derived
Derived is-a Base
Derived implements IThing
class Part
class Aggregate
Aggregate has-a Part
Буду в отпуске, сяду и напишу парсер этого и конвертор в DOT.
Stretch goal: какой-нибудь способ указать, что одни «node1 relation node2» отображать рёбрами, а другие - вложением в кластер-подграф. Типа nginx deployed-on cache-server.
This entry was originally posted at
http://yurikhan.dreamwidth.org/65344.html.