Reword docs: Mention that BriDoc trees are DAGs

pull/35/head
Lennart Spitzner 2017-05-21 13:56:20 +02:00
parent 4ee44388f7
commit 647fa94ef3
5 changed files with 45 additions and 39 deletions

View File

@ -170,7 +170,7 @@ main = do
["module header", "modulechildren"] ["module header", "modulechildren"]
subContext "bridocgen" $ Text.Lazy.unlines subContext "bridocgen" $ Text.Lazy.unlines
[ "translation into BriDoc tree" [ "translation into BriDoc tree/DAG"
, "in (nested) monadic context" , "in (nested) monadic context"
, "(additional) State: NodeAllocIndex" , "(additional) State: NodeAllocIndex"
] ]
@ -270,17 +270,17 @@ main = do
dataTransformationLabeled "layoutSig" dataTransformationLabeled "layoutSig"
"layoutSig\n+recursion\n(layoutType etc.)" "layoutSig\n+recursion\n(layoutType etc.)"
[("type of node?", Just "type sig")] [("type of node?", Just "type sig")]
["BriDoc (tree)"] ["BriDoc (tree/DAG)"]
dataTransformationLabeled "layoutBind" dataTransformationLabeled "layoutBind"
"layoutBind\n+recursion\n(layoutExpr etc.)" "layoutBind\n+recursion\n(layoutExpr etc.)"
[("type of node?", Just "equation")] [("type of node?", Just "equation")]
["BriDoc (tree)"] ["BriDoc (tree/DAG)"]
dataTransformationLabeled "layoutByExact" dataTransformationLabeled "layoutByExact"
"layoutByExact" "layoutByExact"
[("type of node?", Just "not handled (yet)")] [("type of node?", Just "not handled (yet)")]
["BriDoc (tree)"] ["BriDoc (tree/DAG)"]
-- backend :: Data.GraphViz.Types.Generalised.DotGraph String -- backend :: Data.GraphViz.Types.Generalised.DotGraph String
-- backend = digraph (Str ("ppm")) $ do -- backend = digraph (Str ("ppm")) $ do

View File

@ -67,27 +67,27 @@
<path fill="none" stroke="#666666" stroke-width="2" d="M204,-243.9551C204,-235.8828 204,-226.1764 204,-217.1817"/> <path fill="none" stroke="#666666" stroke-width="2" d="M204,-243.9551C204,-235.8828 204,-226.1764 204,-217.1817"/>
<polygon fill="#666666" stroke="#666666" stroke-width="2" points="207.5001,-217.0903 204,-207.0904 200.5001,-217.0904 207.5001,-217.0903"/> <polygon fill="#666666" stroke="#666666" stroke-width="2" points="207.5001,-217.0903 204,-207.0904 200.5001,-217.0904 207.5001,-217.0903"/>
</g> </g>
<!-- BriDoc (tree) --> <!-- BriDoc (tree/DAG) -->
<g id="node4" class="node"> <g id="node4" class="node">
<title>BriDoc (tree)</title> <title>BriDoc (tree/DAG)</title>
<polygon fill="#d3d3d3" stroke="#d3d3d3" points="259,-36 149,-36 149,0 259,0 259,-36"/> <polygon fill="#d3d3d3" stroke="#d3d3d3" points="278,-36 130,-36 130,0 278,0 278,-36"/>
<text text-anchor="middle" x="204" y="-14.3" font-family="Times,serif" font-size="14.00" fill="#000000">BriDoc (tree)</text> <text text-anchor="middle" x="204" y="-14.3" font-family="Times,serif" font-size="14.00" fill="#000000">BriDoc (tree/DAG)</text>
</g> </g>
<!-- layoutSig&#45;&gt;BriDoc (tree) --> <!-- layoutSig&#45;&gt;BriDoc (tree/DAG) -->
<g id="edge3" class="edge"> <g id="edge3" class="edge">
<title>layoutSig&#45;&gt;BriDoc (tree)</title> <title>layoutSig&#45;&gt;BriDoc (tree/DAG)</title>
<path fill="none" stroke="#666666" stroke-width="2" d="M104.6047,-72.9474C122.8312,-62.8715 144.0469,-51.1431 162.1855,-41.1157"/> <path fill="none" stroke="#666666" stroke-width="2" d="M104.6047,-72.9474C122.8312,-62.8715 144.0469,-51.1431 162.1855,-41.1157"/>
<polygon fill="#666666" stroke="#666666" stroke-width="2" points="164.2999,-43.9462 171.3583,-36.0449 160.9132,-37.8199 164.2999,-43.9462"/> <polygon fill="#666666" stroke="#666666" stroke-width="2" points="164.2999,-43.9462 171.3583,-36.0449 160.9132,-37.8199 164.2999,-43.9462"/>
</g> </g>
<!-- layoutBind&#45;&gt;BriDoc (tree) --> <!-- layoutBind&#45;&gt;BriDoc (tree/DAG) -->
<g id="edge5" class="edge"> <g id="edge5" class="edge">
<title>layoutBind&#45;&gt;BriDoc (tree)</title> <title>layoutBind&#45;&gt;BriDoc (tree/DAG)</title>
<path fill="none" stroke="#666666" stroke-width="2" d="M204,-72.9474C204,-64.5354 204,-54.9716 204,-46.2075"/> <path fill="none" stroke="#666666" stroke-width="2" d="M204,-72.9474C204,-64.5354 204,-54.9716 204,-46.2075"/>
<polygon fill="#666666" stroke="#666666" stroke-width="2" points="207.5001,-46.0449 204,-36.0449 200.5001,-46.0449 207.5001,-46.0449"/> <polygon fill="#666666" stroke="#666666" stroke-width="2" points="207.5001,-46.0449 204,-36.0449 200.5001,-46.0449 207.5001,-46.0449"/>
</g> </g>
<!-- layoutByExact&#45;&gt;BriDoc (tree) --> <!-- layoutByExact&#45;&gt;BriDoc (tree/DAG) -->
<g id="edge7" class="edge"> <g id="edge7" class="edge">
<title>layoutByExact&#45;&gt;BriDoc (tree)</title> <title>layoutByExact&#45;&gt;BriDoc (tree/DAG)</title>
<path fill="none" stroke="#666666" stroke-width="2" d="M306.4871,-78.4905C287.7815,-67.45 263.6397,-53.2009 243.4861,-41.3057"/> <path fill="none" stroke="#666666" stroke-width="2" d="M306.4871,-78.4905C287.7815,-67.45 263.6397,-53.2009 243.4861,-41.3057"/>
<polygon fill="#666666" stroke="#666666" stroke-width="2" points="245.2224,-38.2664 234.8315,-36.1975 241.6643,-44.2947 245.2224,-38.2664"/> <polygon fill="#666666" stroke="#666666" stroke-width="2" points="245.2224,-38.2664 234.8315,-36.1975 241.6643,-44.2947 245.2224,-38.2664"/>
</g> </g>

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

@ -20,7 +20,7 @@
<g id="node7" class="node"> <g id="node7" class="node">
<title>bridocgen</title> <title>bridocgen</title>
<ellipse fill="none" stroke="#000000" cx="278.5" cy="-982.6432" rx="187.2667" ry="37.4533"/> <ellipse fill="none" stroke="#000000" cx="278.5" cy="-982.6432" rx="187.2667" ry="37.4533"/>
<text text-anchor="middle" x="278.5" y="-993.9432" font-family="Times,serif" font-size="14.00" fill="#000000">translation into BriDoc tree</text> <text text-anchor="middle" x="278.5" y="-993.9432" font-family="Times,serif" font-size="14.00" fill="#000000">translation into BriDoc tree/DAG</text>
<text text-anchor="middle" x="278.5" y="-978.9432" font-family="Times,serif" font-size="14.00" fill="#000000">in (nested) monadic context</text> <text text-anchor="middle" x="278.5" y="-978.9432" font-family="Times,serif" font-size="14.00" fill="#000000">in (nested) monadic context</text>
<text text-anchor="middle" x="278.5" y="-963.9432" font-family="Times,serif" font-size="14.00" fill="#000000">(additional) State: NodeAllocIndex</text> <text text-anchor="middle" x="278.5" y="-963.9432" font-family="Times,serif" font-size="14.00" fill="#000000">(additional) State: NodeAllocIndex</text>
</g> </g>

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

@ -100,12 +100,14 @@ used in exactly that manner: Both are referenced once in each of the two
alternatives. alternatives.
Unfortunately this does not mean that we can forget this issue entirely. Unfortunately this does not mean that we can forget this issue entirely.
The problem is that the BriDoc tree value will get transformed by multiple The problem is that the BriDoc tree (or maybe: rooted DAG, given that we share
transformations. And this "breaks" sharing: If we take an exponential-sized nodes) value will get transformed by multiple transformations.
tree that is linear-via-sharing and `fmap` some function `f` on it (think of And this "breaks" sharing: If we naively traverse every path in a DAG and
some general-purpose tree that is Functor) then `f` will be evaluated an `fmap` some function `f` on it (think of some general-purpose tree/graph that
exponential number of times. And worse, the output will have lost any sharing. is Functor) then `f` will be evaluated an exponential number of times, because
Sharing is not automatic memoization. our linear DAG still has an exponential amount of different paths.
And worse, the output will have lost any sharing, so becomes a tree with an
exponential number of nodes. Sharing is not automatic memoization.
And this holds for BriDoc, even when the transformations are not exactly And this holds for BriDoc, even when the transformations are not exactly
`fmap`s. `fmap`s.
@ -123,12 +125,14 @@ So.. we already mentioned "memoization" there, right?
we can abstract over that pretty well. we can abstract over that pretty well.
2. The good news: 2. The good news:
With manual memoization, creating an exponentially-sized tree is no With manual memoization, we really work on rooted DAGs
problem, presuming that it is linear-via-sharing. Not messing up this (with linear amount of nodes and edges) instead of trees, because we share
property can take a bit of consideration - but otherwise we are set. nodes. Not messing up this property (that we always share nodes where
If the `BriDocF` tree is exponential, the transformations will still necessary) can take a bit of consideration - but otherwise we are set.
do only linear-amount of "selection work" in order to convert into a Transformations on this DAG can be expressed in such a way that they only
linear-sized `BriDoc` tree. require a linear amount of work, and our first transformation will output
a (linear-sized) tree, so there is relatively little code that needs to
handle a DAG.
This property is the defining one that motivates the BriDoc This property is the defining one that motivates the BriDoc
intermediate representation. intermediate representation.
@ -161,7 +165,7 @@ The `BriDocF f` type encapsulates the idea that each subnode is wrapped
in the `f` container. This notion gives us the following nice properties: in the `f` container. This notion gives us the following nice properties:
`BriDocF Identity ~ BriDoc` and `BriDocF ((,) Int)` is the `BriDocF Identity ~ BriDoc` and `BriDocF ((,) Int)` is the
manual-memoization tree with labeled nodes. Abstractions, abstractions.. manual-memoization tree/DAG with labeled nodes. Abstractions, abstractions..
Lets have a glance at related code/types we have so far: Lets have a glance at related code/types we have so far:
@ -169,8 +173,8 @@ Lets have a glance at related code/types we have so far:
-- The pure BriDoc: What we really want, but cannot use everywhere due -- The pure BriDoc: What we really want, but cannot use everywhere due
-- to sharing issues. -- to sharing issues.
-- Isomorphic to `BriDocF Identity`. We still use this type, because -- Isomorphic to `BriDocF Identity`. We still use this type, because
-- then we have to unwrap the `Identities` only in once place after reducing -- then we have to unwrap the `Identities` only in once place after turning
-- the tree to a non-exponentially-sized one. -- the DAG into a tree (and getting rid of any exponentiality in the process).
data BriDoc data BriDoc
= BDEmpty = BDEmpty
| BDLit !Text | BDLit !Text

View File

@ -102,7 +102,7 @@ consider the circumstances for which a non-optimal solution is returned.
## The Reasoning ## The Reasoning
A top-down approach is so bad, because when there are exponentially many A top-down approach is so bad because when there are exponentially many
layouts to consider, there information passed down from the parents does layouts to consider, there information passed down from the parents does
not help at all in pruning the alternatives on a given layer. In the above not help at all in pruning the alternatives on a given layer. In the above
`nestedCaseExpr` example, we might obtain a better solution by looking not `nestedCaseExpr` example, we might obtain a better solution by looking not
@ -211,14 +211,16 @@ required per node of the input.
which abstracts of different syntactical constructs and only considers the which abstracts of different syntactical constructs and only considers the
things relevant for layouting. This data-type is called `BriDoc`. things relevant for layouting. This data-type is called `BriDoc`.
- The `BriDoc` tree has an exponential number of nodes, but it is linear when - If we did not share values, we'd work on `BriDoc` trees of exponential size.
sharing is considered - the child-nodes can (and must) be re-used across By sharing child-nodes across different alternatives we instead obtain a
different alternatives. In the `nestedCaseExpr` example above, note how rooted DAG of linear size, but still with an exponential number of different
there are four layouts, but essentially only two ways in which the "if" is paths.
layouted. Either as a single line or with then/else on new lines. We can In the `nestedCaseExpr` example above, note how there are four layouts, but
handle spacings in such a way that we can share them for 1/3 and 2/4. This essentially only two ways in which the "if" is layouted.
already hints at how "columns used" will need to be redesigned slightly so Either as a single line or with then/else on new lines. We can handle
that 2/4 really have the same spacing label at the "if". spacings in such a way that we can share them for 1/3 and 2/4.
This already hints at how "columns used" will need to be redesigned slightly
so that 2/4 really have the same spacing label at the "if".
### Concessions/non-Optimality ### Concessions/non-Optimality