shrub/nix/nixcrpkgs/support/graph.rb
benjamin-tlon edd57d380d
Finish cc-release cross-compilation. (#1202)
- 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.
2019-04-23 19:50:38 -07:00

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