45 lines
1.2 KiB
Ruby
45 lines
1.2 KiB
Ruby
# ShortestPaths example, from figure 1 of "Logic and lattices for
|
|
# distributed programming", Conway et. al, UCB tech report, 2012
|
|
#
|
|
# Modified slightly:
|
|
# - added "bootstrap" section to give the algorithm some data
|
|
# - added "stdio <~ ..." to monitor results
|
|
# - added boilerplate to kickstart the program
|
|
# - repurposed next_hop field to track seen-set to avoid nontermination
|
|
|
|
require 'rubygems'
|
|
require 'bud'
|
|
require 'set'
|
|
|
|
class ShortestPaths
|
|
include Bud
|
|
|
|
state do
|
|
table :link, [:from, :to] => [:cost]
|
|
scratch :path, [:from, :to, :seen, :cost]
|
|
scratch :min_cost, [:from, :to] => [:cost]
|
|
end
|
|
|
|
bootstrap do
|
|
link <= [[1, 3, -2],
|
|
[2, 1, 4],
|
|
[2, 3, 3],
|
|
[3, 4, 2],
|
|
[4, 2, -1]]
|
|
end
|
|
|
|
bloom do
|
|
path <= link {|l| [l.from, l.to, Set.new.add(l.from).add(l.to), l.cost]}
|
|
path <= (link*path).pairs(:to => :from) do |l,p|
|
|
[l.from, p.to, p.seen.clone.add(l.from), l.cost + p.cost] if not p.seen.include?(l.from)
|
|
end
|
|
min_cost <= path.group([:from, :to], min(:cost))
|
|
|
|
stdio <~ path { |p| ["path" + p.to_s] }
|
|
stdio <~ min_cost { |m| ["min_cost" + m.to_s] }
|
|
end
|
|
end
|
|
|
|
program = ShortestPaths.new()
|
|
program.run_fg
|