Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add isAcyclic, topSort, dfs and other graph analysis functions to ToGraph #105

Closed
fosskers opened this issue Aug 2, 2018 · 9 comments
Closed

Comments

@fosskers
Copy link
Contributor

fosskers commented Aug 2, 2018

Or likewise, isCircular. Basically, a top-level function to determine if some Graph type is a DAG or not.

As last time (thanks again), I suspect there's some composition of the exposed primitives that "just works", but nothing jumped out at me after a brief scan of the API.

Thoughts?

@snowleopard
Copy link
Owner

snowleopard commented Aug 2, 2018

@fosskers Thanks! I agree, this is a useful function to add. If you don't necessarily need a polymorphic function, the implementation is quite simple:

isDag :: Ord a => AdjacencyMap a -> Bool
isDag = isJust . topSort

You'll just need to convert your graph data type to AdjacencyMap.

With the new ToGraph type class (coming soon in algebraic-graphs-0.2), I believe we could even add it as a separate method, giving you isAcyclic :: (ToGraph g, Ord (ToVertex g)) => g -> Bool.

@fosskers
Copy link
Contributor Author

fosskers commented Aug 2, 2018

Ah ha! So it was just a simple thing. And luckily for me, I'm already using AdjacencyMap.

From the Haddocks:

Compute the topological sort of a graph or return Nothing if the graph is cyclic.

Perhaps I should have used my eyes to read 😢

@snowleopard
Copy link
Owner

No problem :) I'll keep the issue open, to remember to add a few methods to ToGraph class. I guess, we'll need to add not just isAcyclic but also topSort, dfs, etc.

@snowleopard snowleopard changed the title [request] isDag :: Graph g => g -> Bool Add isAcyclic, topSort, dfs and other graph analysis functions to ToGraph Aug 2, 2018
@fosskers
Copy link
Contributor Author

fosskers commented Aug 2, 2018

So isJust . topSort tells us if there's a cycle, which by itself is still very useful. Would it be hard to report the values of the vertices that are causing the cycle?

@snowleopard
Copy link
Owner

snowleopard commented Aug 2, 2018

@fosskers To find the cycle, you can use the scc function. It returns you a graph whose vertices are strongly-connected components, and if any component contains more than a single vertex it is a cycle.

Here is one possible way to use is:

cycles :: Ord a => AdjacencyMap a -> [AdjacencyMap a]
cycles x = [ induce (`Set.member` c) x | c <- cs ]
  where
    cs = filter (\c -> Set.size c > 1) $ vertexList (scc x)

We obtain the list cs which contains non-singleton components (i.e. cyclic subgraphs), and then compute corresponding induced subgraphs of the original graph. As a result you can see all cycles in isolation.

For example:

> cycles $ path [1, 2, 3]
[]

> cycles $ circuit [1, 2, 3]
[edges [(1,2),(2,3),(3,1)]]

> cycles $ circuit [1, 2, 3] + path [3, 4, 5] + circuit [5, 6, 7]
[edges [(1,2),(2,3),(3,1)],edges [(5,6),(6,7),(7,5)]]

@fosskers
Copy link
Contributor Author

fosskers commented Aug 2, 2018

Holy crap that's fantastic. I'm going to try that out right away.

@fosskers
Copy link
Contributor Author

fosskers commented Aug 2, 2018

Alright, looking good! Thanks a lot, once again.

@fosskers fosskers closed this as completed Aug 2, 2018
@snowleopard
Copy link
Owner

@fosskers Great! I'll keep this issue open -- isAcyclic seems like a useful function to add to the API.

@snowleopard snowleopard reopened this Aug 2, 2018
@fosskers
Copy link
Contributor Author

fosskers commented Aug 2, 2018

Woops, my bad.

snowleopard added a commit that referenced this issue Aug 4, 2018
snowleopard added a commit that referenced this issue Aug 9, 2018
* Add comments

* Add conversion to adjacency map data types

* Minor revision

* Extend ToGraph, add isAcyclic

See #105

* Fix Haddock warnings

* Minor revision

* Update the testsuite

* Update change log

* Add reachability analysis

* Fix typo

* Fix another typo

* Update change log

* Optimise edgeCount, drop unnecessary redefinitions in ToGraph Graph instance

* Switch to naming consistent with ToGraph

* Simplify edgeSet, fix GHC 7.8.4 compile error

* Minor revision

* Use stars
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants