Graphs have these properties:
The type 'Edge' represents an edge between two nodes.
data Edge v = Edge {source :: v, target :: v}
deriving (Show,Eq,Ord)
The 'Graph' type represents a directed graph.
data Graph v = Graph {nodes :: Set v, edges :: Set (Edge v)}
deriving Show
The fuction 'isDAG' tests if a graph is acyclic.
isDAG :: Ord v => Graph v -> Bool
isDAG g = isValid g && all nocycle (nodes g)
where nocycle v = all (\a -> v `notMember` reachable g a) $ Set.map target (adj g v)
The fuction 'isForest' tests if a valid DAG is a forest (a set of trees)
isForest :: Ord v => DAG v -> Bool
isForest g = isDAG g && all (\v -> length (adj g v) <= 1) (nodes g)
The generators code is:
DAGs generator
dag :: (Ord v, Arbitrary v) => Gen (DAG v)
dag = arbitrary `suchThat` isDAG
Forests generator
forest :: (Ord v, Arbitrary v) => Gen (Forest v)
forest = arbitrary `suchThat` isForest
I want to improve the generators Dag and Forest, so they are defined based on their properties and not with 'suchThat'. How can I do it?
Thank you in advance.