mirror of
https://github.com/urbit/shrub.git
synced 2024-12-23 10:52:12 +03:00
edd57d380d
- Fixes the IPC bug - Fixes the terminfo bug - Moves the OSX SDK out of our nixcrpkgs fork. - Vendor nixcrpkgs instead of having it be a submodule.
75 lines
1.6 KiB
Ruby
75 lines
1.6 KiB
Ruby
def print_graph(graph)
|
|
graph.each do |parent, children|
|
|
puts "#{parent} ->"
|
|
children.each do |child|
|
|
puts " #{child}"
|
|
end
|
|
end
|
|
end
|
|
|
|
def check_graph!(graph)
|
|
graph.each do |parent, children|
|
|
children.each do |child|
|
|
if !graph.key?(child)
|
|
raise "Graph is missing an entry for #{child}"
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def depth_first_search_exclude_start(graph, start)
|
|
stack = [graph.fetch(start).to_a.reverse]
|
|
visited = Set.new
|
|
until stack.empty?
|
|
node = stack.last.pop
|
|
if node.nil?
|
|
stack.pop
|
|
next
|
|
end
|
|
next if visited.include?(node)
|
|
visited << node
|
|
stack << graph.fetch(node).to_a.reverse
|
|
yield node
|
|
end
|
|
end
|
|
|
|
def transitive_closure(graph)
|
|
tc = {}
|
|
graph.each_key do |node|
|
|
tc[node] = enum_for(:depth_first_search_exclude_start, graph, node).to_a
|
|
end
|
|
tc
|
|
end
|
|
|
|
def restricted_transitive_closure(graph, allowed)
|
|
rtc = {}
|
|
graph.each_key do |node|
|
|
next if !allowed.include?(node)
|
|
reached_nodes = []
|
|
depth_first_search_exclude_start(graph, node) do |reached_node|
|
|
next if !allowed.include?(reached_node)
|
|
reached_nodes << reached_node
|
|
end
|
|
rtc[node] = reached_nodes
|
|
end
|
|
rtc
|
|
end
|
|
|
|
def transitive_reduction(graph)
|
|
tr = {}
|
|
graph.each do |start_node, nodes|
|
|
nodes_with_max_distance_1 = Set.new(nodes)
|
|
distance = 1
|
|
until nodes.empty?
|
|
nodes = Set.new nodes.flat_map &graph.method(:fetch)
|
|
nodes_with_max_distance_1 -= nodes
|
|
distance += 1
|
|
if distance > graph.size
|
|
raise "Cycle detected: this algorithm only works with DAGs."
|
|
end
|
|
end
|
|
tr[start_node] = nodes_with_max_distance_1.to_a
|
|
end
|
|
tr
|
|
end
|