diff --git a/doc-svg-gen/Main.hs b/doc-svg-gen/Main.hs
index 11baa98..55861ac 100644
--- a/doc-svg-gen/Main.hs
+++ b/doc-svg-gen/Main.hs
@@ -170,7 +170,7 @@ main = do
["module header", "modulechildren"]
subContext "bridocgen" $ Text.Lazy.unlines
- [ "translation into BriDoc tree"
+ [ "translation into BriDoc tree/DAG"
, "in (nested) monadic context"
, "(additional) State: NodeAllocIndex"
]
@@ -270,17 +270,17 @@ main = do
dataTransformationLabeled "layoutSig"
"layoutSig\n+recursion\n(layoutType etc.)"
[("type of node?", Just "type sig")]
- ["BriDoc (tree)"]
+ ["BriDoc (tree/DAG)"]
dataTransformationLabeled "layoutBind"
"layoutBind\n+recursion\n(layoutExpr etc.)"
[("type of node?", Just "equation")]
- ["BriDoc (tree)"]
+ ["BriDoc (tree/DAG)"]
dataTransformationLabeled "layoutByExact"
"layoutByExact"
[("type of node?", Just "not handled (yet)")]
- ["BriDoc (tree)"]
+ ["BriDoc (tree/DAG)"]
-- backend :: Data.GraphViz.Types.Generalised.DotGraph String
-- backend = digraph (Str ("ppm")) $ do
diff --git a/doc-svg-gen/generated/bridocgen.svg b/doc-svg-gen/generated/bridocgen.svg
index 78ca446..841e4ee 100644
--- a/doc-svg-gen/generated/bridocgen.svg
+++ b/doc-svg-gen/generated/bridocgen.svg
@@ -67,27 +67,27 @@
-
+
-BriDoc (tree)
-
-BriDoc (tree)
+BriDoc (tree/DAG)
+
+BriDoc (tree/DAG)
-
+
-layoutSig->BriDoc (tree)
+layoutSig->BriDoc (tree/DAG)
-
+
-layoutBind->BriDoc (tree)
+layoutBind->BriDoc (tree/DAG)
-
+
-layoutByExact->BriDoc (tree)
+layoutByExact->BriDoc (tree/DAG)
diff --git a/doc-svg-gen/generated/ppm.svg b/doc-svg-gen/generated/ppm.svg
index 3f11681..1e737ed 100644
--- a/doc-svg-gen/generated/ppm.svg
+++ b/doc-svg-gen/generated/ppm.svg
@@ -20,7 +20,7 @@
bridocgen
-translation into BriDoc tree
+translation into BriDoc tree/DAG
in (nested) monadic context
(additional) State: NodeAllocIndex
diff --git a/docs/implementation/bridoc-design.md b/docs/implementation/bridoc-design.md
index c0f95e8..86bf069 100644
--- a/docs/implementation/bridoc-design.md
+++ b/docs/implementation/bridoc-design.md
@@ -100,12 +100,14 @@ used in exactly that manner: Both are referenced once in each of the two
alternatives.
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
-transformations. And this "breaks" sharing: If we take an exponential-sized
-tree that is linear-via-sharing and `fmap` some function `f` on it (think of
-some general-purpose tree that is Functor) then `f` will be evaluated an
-exponential number of times. And worse, the output will have lost any sharing.
-Sharing is not automatic memoization.
+The problem is that the BriDoc tree (or maybe: rooted DAG, given that we share
+nodes) value will get transformed by multiple transformations.
+And this "breaks" sharing: If we naively traverse every path in a DAG and
+`fmap` some function `f` on it (think of some general-purpose tree/graph that
+is Functor) then `f` will be evaluated an exponential number of times, because
+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
`fmap`s.
@@ -123,12 +125,14 @@ So.. we already mentioned "memoization" there, right?
we can abstract over that pretty well.
2. The good news:
- With manual memoization, creating an exponentially-sized tree is no
- problem, presuming that it is linear-via-sharing. Not messing up this
- property can take a bit of consideration - but otherwise we are set.
- If the `BriDocF` tree is exponential, the transformations will still
- do only linear-amount of "selection work" in order to convert into a
- linear-sized `BriDoc` tree.
+ With manual memoization, we really work on rooted DAGs
+ (with linear amount of nodes and edges) instead of trees, because we share
+ nodes. Not messing up this property (that we always share nodes where
+ necessary) can take a bit of consideration - but otherwise we are set.
+ Transformations on this DAG can be expressed in such a way that they only
+ 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
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:
`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:
@@ -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
-- to sharing issues.
-- Isomorphic to `BriDocF Identity`. We still use this type, because
--- then we have to unwrap the `Identities` only in once place after reducing
--- the tree to a non-exponentially-sized one.
+-- then we have to unwrap the `Identities` only in once place after turning
+-- the DAG into a tree (and getting rid of any exponentiality in the process).
data BriDoc
= BDEmpty
| BDLit !Text
diff --git a/docs/implementation/theory.md b/docs/implementation/theory.md
index 31e5e92..f01b1ba 100644
--- a/docs/implementation/theory.md
+++ b/docs/implementation/theory.md
@@ -102,7 +102,7 @@ consider the circumstances for which a non-optimal solution is returned.
## 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
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
@@ -211,14 +211,16 @@ required per node of the input.
which abstracts of different syntactical constructs and only considers the
things relevant for layouting. This data-type is called `BriDoc`.
-- The `BriDoc` tree has an exponential number of nodes, but it is linear when
- sharing is considered - the child-nodes can (and must) be re-used across
- different alternatives. In the `nestedCaseExpr` example above, note how
- there are four layouts, but essentially only two ways in which the "if" is
- layouted. Either as a single line or with then/else on new lines. We can
- handle 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".
+- If we did not share values, we'd work on `BriDoc` trees of exponential size.
+ By sharing child-nodes across different alternatives we instead obtain a
+ rooted DAG of linear size, but still with an exponential number of different
+ paths.
+ In the `nestedCaseExpr` example above, note how there are four layouts, but
+ essentially only two ways in which the "if" is layouted.
+ Either as a single line or with then/else on new lines. We can handle
+ 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