Closed rolyp closed 1 year ago
As described in a bullet point in #634, we have some considerations on how we are going to implement the dependence graphs: There are 3 main representations for graphs in general:
We need to choose the best option based both on the asymptotic performance of the operations we are going to perform the most often, but also to bear in mind the most efficient purescript representations (in particular I need to consider ForeignObject and maybe StringMap)
We can also consider some other more algorithmic concerns, for example if we can calculate the number of nodes we are going to need ahead of time, we could allocate the entire matrix in one go and then fill in the edge entries efficiently. Will fill in this issue as I gather more information
Hi @JosephBond. A good way to proceed here would be to define an interface (in the form of a type class) which is just rich enough to support the implementation of the graph semantics (Fig. 13). For now we probably just need the ability to allocate a fresh vertex and merge two graphs with disjoint keys (perhaps optimised for the singleton case). If we can get this in place first, Min can make a start on the graph evaluation while you finalise the internal representation. We may be able to use newtype
to implement $G^{-1}$. I’ve added some corresponding todo’s to the issue body.
At this stage, keeping things simple seems to be the best option, to that end we will start with an Adjacency list representation, built off ForeignObject (as they seem to be quite snappy, which is obviously a benefit to us).
I need to do a little more work on the representation itself before we can start implementing the semantics, in particular we will probably want/need some other typeclasses implemented for the graphs so that Min can work with usual functional design patterns
Something like the following should be enough to implement graph eval
:
module Graph where
import Data.Set (Set)
import Util (Endo)
newtype Vertex = Vertex String
class Graph g where
-- deterministic for now
fresh :: g -> Vertex
-- optimised for singleton case for now
disjUnion :: Vertex -> Set Vertex -> Endo g
Updated to subsume disjUnion
by union
, and add methods required for forward and backward slicing:
class Graph g where
-- fresh vertex; deterministic for now
fresh :: g -> Vertex
-- union with another (singleton) graph
union :: Vertex -> Set Vertex -> Endo g
-- out-neighbours
outN :: g -> Vertex -> Set Vertex
-- singleton graph
singleton :: Vertex -> Set Vertex -> g
-- remove vertex and associated edges
remove :: Vertex -> Endo g
-- opposite graph
opp :: Endo g
Hi Joe, looks like a reasonable start! Some initial comments/suggestions:
Tuple
DependenceGraph
to Graph
for nowSimpleGraph
probably isn’t a good name as it’s a technical term in graph theory; maybe GraphImpl
, or something suggested by the efficient opp
implementation (see below)opp
, let’s use the implementation we discussed last week with Cristina: maintain a pair of Object (Set Vertex)
maps, one for each direction, and then implement opp
as swap
union
as currently implemented isn’t commutative: it needs to combine the entries for any overlapping keys using union
(using unionWith
)outN
should be undefined (rather than empty
) if α $\notin g$singleton
needs to have a key for every neighbour as well (mapping to the empty set)\node -> (Tuple v node)
as (Tuple v _)
derive instance Newtype Vertex _
will give you unwrap
Hi @JosephBond. A summary of what I can see as the remaining outstanding implementation tasks; then I think you’re good to close off this issue and move onto #639 and #638. (I agree it would be good to start thinking about performance testing too, but starting on slicing will be exciting and will also thrash out remaining issues with the Graph
interface!)
unwrap
, AnnGraph
, allEdges
, adjEdges
and reverseEdges
)inStar
/outStar
implementations (either foldl
with SM.insert
rather than unionWith union
, or use SM.fromFoldable
)outN
is probably preferable to getOutN
for the name of the class method; the local variables outN
and inN
could be renamed to out
and in_
or similar
Graph
type class presenting API required to implement graph evaluation