disco-0.1.0.0: lib/graph.disco
search : N -> Graph(N) -> N -> Bool * Set(N)
search target g pos = {?
(search' target g pos {}) if (contains g pos),
(False, {}) otherwise
?}
search' : N -> Graph(N) -> N -> Set(N) -> Bool * Set(N)
search' target g pos visited = {?
(True, visited union {pos}) if (pos == target && contains g pos),
(False,visited) if pos ∈ visited,
sequence target g pos (list (neighbors g pos)) (visited union {pos}) otherwise
?}
sequence : N -> Graph(N) -> N -> List(N) -> Set(N) -> Bool * Set(N)
sequence target g pos [] visited = (False, visited)
sequence target g pos (a::as) visited =
{? {?
(successful, v') if successful,
sequence target g pos as v' otherwise
?} when search' target g a visited is (successful, v')
?}
searchDAG : N -> Graph(N) -> N -> Bool
searchDAG target g pos = (pos == target && contains g pos) || (true ∈ (each (searchDAG target g, neighbors g pos)))
contains : Graph(N) -> N -> Bool
contains g a = {?
True when lookup (a,summary g) is right _,
False otherwise
?}
neighbors : Graph(N) -> N -> Set(N)
neighbors g pos = {?
s when lookup (pos, summary g) is right s,
{} otherwise
?}
vertices : Graph(N) -> List(N)
vertices g = each ((\(k,_). k), (list (mapToSet (summary g))))
topsort : Graph(N) -> Unit + List(N) * Set(N)
topsort g = downstream g (vertices g) {} {} []
searchFrom' : Graph(N) -> N -> Set(N) -> Set(N) -> List(N) -> Unit + List(N) * Set(N)
searchFrom' g pos visited locked stack = {?
left(unit) if pos ∈ locked,
right (stack, visited) if pos ∈ visited,
right (pos :: s', v' union {pos}) when downstream g (list (neighbors g pos)) visited (locked union {pos}) stack is right (s', v'),
left(unit) otherwise
?}
downstream : Graph(N) -> List(N) -> Set(N) -> Set(N) -> List(N) -> Unit + List(N) * Set(N)
downstream g [] visited locked stack = right (stack, visited)
downstream g (a::as) visited locked stack =
{?
downstream g as v' locked s' when searchFrom' g a visited locked stack is right (s',v'),
left(unit) otherwise
?}