art-decomp 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +2 -0
- data/LICENCE +661 -0
- data/README +9 -0
- data/Rakefile +46 -0
- data/VERSION +1 -0
- data/bin/ad-compare +22 -0
- data/bin/ad-console +11 -0
- data/bin/ad-inputs +24 -0
- data/bin/ad-validate +9 -0
- data/bin/art-decomp +8 -0
- data/lib/art-decomp/arch.rb +32 -0
- data/lib/art-decomp/b.rb +7 -0
- data/lib/art-decomp/bipainter.rb +142 -0
- data/lib/art-decomp/blanket.rb +82 -0
- data/lib/art-decomp/decomposer.rb +75 -0
- data/lib/art-decomp/decomposition.rb +91 -0
- data/lib/art-decomp/exceptions.rb +9 -0
- data/lib/art-decomp/executable.rb +94 -0
- data/lib/art-decomp/fsm.rb +128 -0
- data/lib/art-decomp/graph.rb +78 -0
- data/lib/art-decomp/kiss.rb +47 -0
- data/lib/art-decomp/logging.rb +52 -0
- data/lib/art-decomp/qu_generator/block_table.rb +42 -0
- data/lib/art-decomp/qu_generator/edge_labels.rb +24 -0
- data/lib/art-decomp/qv_generator/bipainting.rb +12 -0
- data/lib/art-decomp/qv_generator/graph_colouring.rb +16 -0
- data/lib/art-decomp/qv_generator/graph_merging.rb +19 -0
- data/lib/art-decomp/sep.rb +7 -0
- data/lib/art-decomp/uv_generator/braindead.rb +22 -0
- data/lib/art-decomp/uv_generator/relevance.rb +23 -0
- data/lib/art-decomp.rb +65 -0
- data/lib/core/enumerable.rb +24 -0
- data/lib/core/file.rb +11 -0
- data/lib/core/integer.rb +13 -0
- data/lib/core/set.rb +16 -0
- data/lib/core/string.rb +13 -0
- data/spec/art-decomp/arch_spec.rb +23 -0
- data/spec/art-decomp/b_spec.rb +27 -0
- data/spec/art-decomp/bipainter_spec.rb +22 -0
- data/spec/art-decomp/blanket_spec.rb +77 -0
- data/spec/art-decomp/decomposer_spec.rb +106 -0
- data/spec/art-decomp/decomposition_spec.rb +119 -0
- data/spec/art-decomp/executable_spec.rb +161 -0
- data/spec/art-decomp/fsm_spec.rb +146 -0
- data/spec/art-decomp/graph_spec.rb +69 -0
- data/spec/art-decomp/kiss_spec.rb +30 -0
- data/spec/art-decomp/logging_spec.rb +62 -0
- data/spec/art-decomp/qu_generator/block_table_spec.rb +37 -0
- data/spec/art-decomp/qu_generator/edge_labels_spec.rb +35 -0
- data/spec/art-decomp/qv_generator/bipainting_spec.rb +28 -0
- data/spec/art-decomp/qv_generator/graph_colouring_spec.rb +31 -0
- data/spec/art-decomp/qv_generator/graph_merging_spec.rb +30 -0
- data/spec/art-decomp/sep_spec.rb +13 -0
- data/spec/art-decomp/uv_generator/braindead_spec.rb +33 -0
- data/spec/art-decomp/uv_generator/relevance_spec.rb +61 -0
- data/spec/core/enumerable_spec.rb +20 -0
- data/spec/core/file_spec.rb +15 -0
- data/spec/core/integer_spec.rb +16 -0
- data/spec/core/set_spec.rb +26 -0
- data/spec/core/string_spec.rb +17 -0
- data/spec/fixtures/ex5 +36 -0
- data/spec/fixtures/fsm +24 -0
- data/spec/fixtures/fsm.exp +40 -0
- data/spec/fixtures/fsm.f +20 -0
- data/spec/fixtures/fsm.g +4 -0
- data/spec/fixtures/fsm.h +19 -0
- data/spec/fixtures/fsm.partially-exp +31 -0
- data/spec/fixtures/fsm.q +10 -0
- data/spec/fixtures/lion +15 -0
- data/spec/fixtures/lion.exp +15 -0
- data/spec/fixtures/lion.h +10 -0
- data/spec/fixtures/lion.to_kiss +11 -0
- data/spec/fixtures/mark1 +26 -0
- data/spec/fixtures/mc +14 -0
- data/spec/fixtures/mc.to_kiss +10 -0
- data/spec/fixtures/opus +26 -0
- data/spec/fixtures/opus.amb.h +22 -0
- data/spec/fixtures/opus.h +21 -0
- data/spec/fixtures/opus.to_kiss +22 -0
- data/spec/fixtures/s420 +142 -0
- data/spec/fixtures/s8 +24 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +8 -0
- metadata +224 -0
@@ -0,0 +1,69 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module ArtDecomp describe Graph do
|
4
|
+
|
5
|
+
before do
|
6
|
+
blanket = Blanket[B[1,2], B[3,4], B[5,6], B[7], B[8,9]]
|
7
|
+
seps = Set[Sep[4,6], Sep[5,9], Sep[5,7], Sep[7,9]]
|
8
|
+
@graph = Graph.new blanket, seps
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should initialise properly from a Blanket and a Set of Seps' do
|
12
|
+
@graph.vertices.should == Set[B[1,2], B[3,4], B[5,6], B[7], B[8,9]]
|
13
|
+
@graph.edges.should == Set[Set[B[3,4], B[5,6]], Set[B[5,6], B[7]], Set[B[8,9], B[7]], Set[B[5,6], B[8,9]]]
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should drop vertices covered by other vertices upon initialisation' do
|
17
|
+
Graph.new(Blanket[B[1,2], B[2]], Set[]).vertices.should == Set[B[1,2]]
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should properly compute vertex degrees' do
|
21
|
+
degrees = {B[1,2] => 0, B[3,4] => 1, B[5,6] => 3, B[7] => 2, B[8,9] => 2}
|
22
|
+
degrees.each { |vert, deg| @graph.degree(vert).should == deg }
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should return the proper Blanket obtained by colouring the vertices' do
|
26
|
+
blanket = @graph.blanket_from_colouring
|
27
|
+
blanket.size.should == 3
|
28
|
+
blanket.ints.should include(B[1,2,5,6])
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should report whether it’s complete' do
|
32
|
+
complete = Graph.new Blanket[B[1], B[2], B[3]], Set[Sep[1,2], Sep[1,3], Sep[2,3]]
|
33
|
+
complete.should be_complete
|
34
|
+
@graph.should_not be_complete
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should properly merge until it’s complete and return self' do
|
38
|
+
@graph.merge_until_complete!.should be_a(Graph)
|
39
|
+
@graph.vertices.size.should == 3
|
40
|
+
@graph.vertices.should include(B[1,2,5,6])
|
41
|
+
@graph.should be_complete
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should properly merge based on edge weights and return self' do
|
45
|
+
b1234 = Blanket[B[1], B[2], B[3], B[4]]
|
46
|
+
graph = Graph.new b1234, b1234.seps
|
47
|
+
graph.merge_by_edge_labels! { |a, b| a | b }.should be_a(Graph)
|
48
|
+
graph.vertices.should == Set[B[1,2,3], B[4]]
|
49
|
+
graph.merge_by_edge_labels! { |a, b| a | b }.should be_a(Graph)
|
50
|
+
graph.vertices.should == Set[B[1,2,3,4]]
|
51
|
+
graph.merge_by_edge_labels! { |a, b| a | b }.should be_a(Graph)
|
52
|
+
graph.vertices.should == Set[B[1,2,3,4]]
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should properly merge based on vertex degrees and return self' do
|
56
|
+
graph = Graph.new Blanket[B[1], B[2], B[3], B[4], B[5], B[6]], Set[Sep[3,4], Sep[4,5], Sep[4,6], Sep[5,6]]
|
57
|
+
graph.merge_by_vertex_degrees!.should be_a(Graph)
|
58
|
+
graph.vertices.should == Set[B[1,2,4], B[3], B[5], B[6]]
|
59
|
+
graph.merge_by_vertex_degrees!.should be_a(Graph)
|
60
|
+
graph.vertices.size.should == 3
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should report a given vertex’s adjacent vertices' do
|
64
|
+
@graph.adjacent(B[3,4]).should == Set[B[5,6]]
|
65
|
+
@graph.adjacent(B[1,2]).should == Set[]
|
66
|
+
@graph.adjacent(B[5,6], B[7]).should == Set[B[3,4], B[8,9]]
|
67
|
+
end
|
68
|
+
|
69
|
+
end end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module ArtDecomp describe KISS do
|
2
|
+
|
3
|
+
it 'should sort entries' do
|
4
|
+
kiss = KISS.new ['1 1', '0 0']
|
5
|
+
kiss.formatted.should == "0 0\n1 1\n"
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should drop non-unique entries' do
|
9
|
+
kiss = KISS.new ['0 0', '0 0']
|
10
|
+
kiss.formatted.should == "0 0\n"
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should drop overlapping entries' do
|
14
|
+
kiss = KISS.new ['0-0 0', '010 0', '1-1 1', '--1 1']
|
15
|
+
kiss.formatted.should == "--1 1\n0-0 0\n"
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should preserve overlapping entries which differ on subsequent column groups' do
|
19
|
+
kiss = KISS.new ['-- 1 0 1', '10 0 0 1']
|
20
|
+
kiss.formatted.should == "-- 1 0 1\n10 0 0 1\n"
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should combine matching entries' do
|
24
|
+
kiss = KISS.new ['00 0 1 1', '01 0 1 1', '10 1 0 0', '11 1 0 0']
|
25
|
+
kiss.formatted.should == "0- 0 1 1\n1- 1 0 0\n"
|
26
|
+
kiss = KISS.new ['00 0', '11 0', '10 0', '01 0']
|
27
|
+
kiss.formatted.should == "-- 0\n"
|
28
|
+
end
|
29
|
+
|
30
|
+
end end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require_relative '../../lib/art-decomp/logging'
|
4
|
+
|
5
|
+
module ArtDecomp describe Logging do
|
6
|
+
|
7
|
+
before do
|
8
|
+
@dir = "#{Dir.tmpdir}/#{rand.to_s}"
|
9
|
+
@log = StringIO.new
|
10
|
+
Logging.log = @log
|
11
|
+
end
|
12
|
+
|
13
|
+
after do
|
14
|
+
Logging.off
|
15
|
+
FileUtils.rmtree @dir if Dir.exists? @dir
|
16
|
+
end
|
17
|
+
|
18
|
+
def log
|
19
|
+
@log.rewind
|
20
|
+
@log.read
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should log Executable’s decompositions calls on simple cases' do
|
24
|
+
args = ['-a', '5/1', '4/2', '-o', @dir, 'spec/fixtures/lion']
|
25
|
+
Executable.new(args).run
|
26
|
+
log.should =~ rex('final best decomposition: 2')
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should log Executable’s decompositions calls on typical cases' do
|
30
|
+
Decomposer.should_receive(:new).and_return mock(Decomposer, :decompositions => [].each)
|
31
|
+
args = ['-a', '5/1', '4/2', '-o', @dir, 'spec/fixtures/fsm']
|
32
|
+
Executable.new(args).run
|
33
|
+
log.should =~ rex('FSM 4/2+10s → 5/1+4/2 () with Relevance, EdgeLabels, GraphColouring – best so far: ')
|
34
|
+
log.should =~ rex('final best decomposition: ')
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should log UVGenerators’ uv_pairs calls' do
|
38
|
+
uv = UVGenerator::Braindead.new mock(FSM, :input_count => 2), Set[Arch[5,1]]
|
39
|
+
uv.uv_pairs
|
40
|
+
log.should =~ rex('UV with Braindead')
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should log QuGenerators’ blankets calls' do
|
44
|
+
qu = QuGenerator::BlockTable.new
|
45
|
+
[[Set[0], Set[1]], [Set[1], Set[0]]].each do |u, v|
|
46
|
+
qu.blankets mock(FSM), u, v
|
47
|
+
end
|
48
|
+
log.should =~ rex('U = [0], V = [1], Qu with BlockTable')
|
49
|
+
log.should =~ rex('U = [1], V = [0], Qu with BlockTable')
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should log QvGenerators’ blankets calls (on the DEBUG level)' do
|
53
|
+
Logging.level = Logger::DEBUG
|
54
|
+
qv = QvGenerator::GraphColouring.new
|
55
|
+
[mock(Blanket, :size => 8), mock(Blanket, :size => 4)].each do |qu|
|
56
|
+
qv.blankets mock(FSM), Set[0], Set[1], qu
|
57
|
+
end
|
58
|
+
log.should =~ rex('|Qu| = 8, Qv+G with GraphColouring')
|
59
|
+
log.should =~ rex('|Qu| = 4, Qv+G with GraphColouring')
|
60
|
+
end
|
61
|
+
|
62
|
+
end end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module ArtDecomp describe QuGenerator::BlockTable do
|
4
|
+
|
5
|
+
context 'when generating Qu blankets' do
|
6
|
+
|
7
|
+
def qus
|
8
|
+
fsm = mock FSM, :beta_f => @beta_f, :beta_q => @beta_q, :beta_x => @beta_x
|
9
|
+
archs = Set[Arch[3,1]]
|
10
|
+
bt = QuGenerator::BlockTable.new
|
11
|
+
bt.blankets(fsm, Set[0], Set[1]).to_a
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should fold Q blocks that match in the first go' do
|
15
|
+
@beta_f = Blanket[]
|
16
|
+
@beta_q = Blanket[B[1,2], B[2], B[3]]
|
17
|
+
@beta_x = Blanket[B[1], B[2], B[3]]
|
18
|
+
qus.first.should == Blanket[B[1,2,3], B[2]]
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'shouldn’t fold Q blocks if they don’t match' do
|
22
|
+
@beta_f = Blanket[]
|
23
|
+
@beta_q = Blanket[B[1,2], B[2,3]]
|
24
|
+
@beta_x = Blanket[B[1], B[2], B[3]]
|
25
|
+
qus.first.should == Blanket[B[1,2], B[2,3]]
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should first try to fold matching blocks and then fold by r-admissibility' do
|
29
|
+
@beta_f = mock Blanket, :seps => Set[Sep[1,2], Sep[2,3]]
|
30
|
+
@beta_q = Blanket[B[1], B[2], B[3]]
|
31
|
+
@beta_x = Blanket[B[1,2,3], B[1,3]]
|
32
|
+
qus.should == [Blanket[B[1], B[2], B[3]], Blanket[B[1,3], B[2]], Blanket[B[1,2,3]]]
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module ArtDecomp describe QuGenerator::EdgeLabels do
|
2
|
+
|
3
|
+
context 'when generating Qu blankets' do
|
4
|
+
|
5
|
+
def qus
|
6
|
+
fsm = mock FSM, :beta_f => @beta_f, :beta_q => @beta_q, :beta_x => @beta_x
|
7
|
+
archs = Set[Arch[3,1]]
|
8
|
+
el = QuGenerator::EdgeLabels.new
|
9
|
+
el.blankets(fsm, Set[0], Set[1]).to_a
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should fist merge until its graph is complete' do
|
13
|
+
@beta_f = mock Blanket, :seps => Set[Sep[1,2], Sep[2,3]]
|
14
|
+
@beta_q = Blanket[B[1], B[2], B[3]]
|
15
|
+
@beta_x = Blanket[]
|
16
|
+
qus.first.should == Blanket[B[1,3], B[2]]
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should then merge blocks based on r-admissibility of the merged block, all the way down' do
|
20
|
+
@beta_f = Blanket[B[1], B[2,3], B[4], B[5], B[6]]
|
21
|
+
@beta_q = Blanket[B[1], B[2,3], B[4,5,6]]
|
22
|
+
@beta_x = Blanket[]
|
23
|
+
qus.should == [Blanket[B[1], B[2,3], B[4,5,6]], Blanket[B[1,2,3], B[4,5,6]], Blanket[B[1,2,3,4,5,6]]]
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should merge blocks based on the number of separations lost (if the r-admissibility is the same)' do
|
27
|
+
@beta_f = Blanket[B[1,2], B[3,4,5], B[6]]
|
28
|
+
@beta_q = Blanket[B[1,2], B[3,4,5], B[6]]
|
29
|
+
@beta_x = Blanket[]
|
30
|
+
qus.should == [Blanket[B[1,2], B[3,4,5], B[6]], Blanket[B[1,2,6], B[3,4,5]], Blanket[B[1,2,3,4,5,6]]]
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module ArtDecomp describe QvGenerator::Bipainting do
|
2
|
+
|
3
|
+
context 'when generating G and Qv blankets' do
|
4
|
+
|
5
|
+
it 'should use graph bicolouring' do
|
6
|
+
beta_f = mock Blanket, :seps => Set[Sep[1,2], Sep[1,3], Sep[1,6], Sep[2,6], Sep[3,4], Sep[3,6], Sep[4,5], Sep[5,6]]
|
7
|
+
beta_q = Blanket[B[1,2], B[3,4], B[5,6]]
|
8
|
+
beta_u = Blanket[]
|
9
|
+
beta_v = Blanket[B[1,3,5], B[2,4,6]]
|
10
|
+
beta_qu = Blanket[]
|
11
|
+
|
12
|
+
fsm = mock FSM, :beta_f => beta_f, :beta_q => beta_q
|
13
|
+
fsm.should_receive(:beta_x).with(Set[0]).and_return beta_u
|
14
|
+
fsm.should_receive(:beta_x).with(Set[1]).and_return beta_v
|
15
|
+
archs = Set[Arch[3,1]]
|
16
|
+
bi = QvGenerator::Bipainting.new
|
17
|
+
|
18
|
+
beta_qv, beta_g = bi.blankets(fsm, Set[0], Set[1], beta_qu).to_a.first
|
19
|
+
beta_qv.should == Blanket[B[1,2], B[3,4,5,6]]
|
20
|
+
beta_g.should == Blanket[B[1], B[2,3,5], B[4,6]]
|
21
|
+
|
22
|
+
beta_f.seps.should be_subset(beta_u.seps + beta_qu.seps + beta_g.seps)
|
23
|
+
beta_g.seps.should be_subset(beta_v.seps + beta_qv.seps)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module ArtDecomp describe QvGenerator::GraphColouring do
|
2
|
+
|
3
|
+
context 'when generating G and Qv blankets' do
|
4
|
+
|
5
|
+
it 'should use graph colouring of the proper incompatibility graphs' do
|
6
|
+
beta_f = mock Blanket, :seps => Set[Sep[1,2], Sep[1,3], Sep[1,6], Sep[2,6], Sep[3,4], Sep[3,6], Sep[4,5], Sep[5,6]]
|
7
|
+
beta_q = Blanket[B[1,2], B[3,4], B[5,6]]
|
8
|
+
beta_u = Blanket[]
|
9
|
+
beta_v = Blanket[B[1,3,5], B[2,4,6]]
|
10
|
+
beta_qu = Blanket[]
|
11
|
+
|
12
|
+
fsm = mock FSM, :beta_f => beta_f, :beta_q => beta_q
|
13
|
+
fsm.should_receive(:beta_x).with(Set[0]).and_return beta_u
|
14
|
+
fsm.should_receive(:beta_x).with(Set[1]).and_return beta_v
|
15
|
+
archs = Set[Arch[3,1]]
|
16
|
+
gc = QvGenerator::GraphColouring.new
|
17
|
+
|
18
|
+
pairs = gc.blankets(fsm, Set[0], Set[1], beta_qu).to_a
|
19
|
+
pairs.size.should == 2
|
20
|
+
pairs.first.should == [Blanket[B[1,2], B[3,4], B[5,6]], Blanket[B[1,5], B[2,3], B[4,6]]]
|
21
|
+
pairs.last.should == [Blanket[B[1,2], B[3,4,5,6]], Blanket[B[1], B[2,3,5], B[4,6]]]
|
22
|
+
|
23
|
+
pairs.each do |beta_qv, beta_g|
|
24
|
+
beta_f.seps.should be_subset(beta_u.seps + beta_qu.seps + beta_g.seps)
|
25
|
+
beta_g.seps.should be_subset(beta_v.seps + beta_qv.seps)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module ArtDecomp describe QvGenerator::GraphMerging do
|
2
|
+
|
3
|
+
context 'when generating G and Qv blankets' do
|
4
|
+
|
5
|
+
it 'should merge vertices of the proper incompatibility graphs' do
|
6
|
+
beta_f = mock Blanket, :seps => Set[Sep[1,2], Sep[1,3], Sep[1,6], Sep[2,6], Sep[3,4], Sep[3,6], Sep[4,5], Sep[5,6]]
|
7
|
+
beta_q = Blanket[B[1,2], B[3,4], B[5,6]]
|
8
|
+
beta_u = Blanket[]
|
9
|
+
beta_v = Blanket[B[1,3,5], B[2,4,6]]
|
10
|
+
beta_qu = Blanket[]
|
11
|
+
|
12
|
+
fsm = mock FSM, :beta_f => beta_f, :beta_q => beta_q
|
13
|
+
fsm.should_receive(:beta_x).with(Set[0]).and_return beta_u
|
14
|
+
fsm.should_receive(:beta_x).with(Set[1]).and_return beta_v
|
15
|
+
archs = Set[Arch[3,1]]
|
16
|
+
gm = QvGenerator::GraphMerging.new
|
17
|
+
|
18
|
+
pairs = gm.blankets(fsm, Set[0], Set[1], beta_qu).to_a
|
19
|
+
pairs.first.should == [Blanket[B[1,2], B[3,4], B[5,6]], Blanket[B[1,5], B[2,3], B[4,6]]]
|
20
|
+
pairs.last.should == [Blanket[B[1,2], B[3,4,5,6]], Blanket[B[1], B[2,3,5], B[4,6]]]
|
21
|
+
|
22
|
+
pairs.each do |beta_qv, beta_g|
|
23
|
+
beta_f.seps.should be_subset(beta_u.seps + beta_qu.seps + beta_g.seps)
|
24
|
+
beta_g.seps.should be_subset(beta_v.seps + beta_qv.seps)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module ArtDecomp describe Sep do
|
2
|
+
|
3
|
+
it 'should be an Integer with bits representing the separated values' do
|
4
|
+
Sep[1,2].should == 0b110
|
5
|
+
Sep[0,69].should == 2**69 + 0b1
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should be usable as a Set element' do
|
9
|
+
Sep[1,2].hash.should == 0b110.hash
|
10
|
+
Sep[0,69].hash.should == (2**69 + 0b1).hash
|
11
|
+
end
|
12
|
+
|
13
|
+
end end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module ArtDecomp describe UVGenerator::Braindead do
|
2
|
+
|
3
|
+
context 'given a certain FSM and a Set of Archs' do
|
4
|
+
|
5
|
+
it 'should yield all non-insane U and V combinations' do
|
6
|
+
fsm = mock FSM, :input_count => 4
|
7
|
+
fsm.stub!(:expand_x).and_return fsm
|
8
|
+
archs = Set[Arch[3,1]]
|
9
|
+
uv_gen = UVGenerator::Braindead.new fsm, archs
|
10
|
+
uvs = uv_gen.uv_pairs.to_a
|
11
|
+
uvs.size.should == 15
|
12
|
+
uvs.first.should == [fsm, Set[0,1,2,3], Set[]]
|
13
|
+
uvs[7].should == [fsm, Set[3], Set[0,1,2]]
|
14
|
+
uvs.last.should == [fsm, Set[0], Set[1,2,3]]
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should yield V-expanded FSMs' do
|
18
|
+
fsm = mock FSM, :input_count => 2
|
19
|
+
fsm0, fsm1, fsm2, fsm3 = mock(FSM), mock(FSM), mock(FSM), mock(FSM)
|
20
|
+
fsm.should_receive(:expand_x).exactly(4).times.and_return(fsm0, fsm1, fsm2, fsm3)
|
21
|
+
archs = Set[Arch[3,1]]
|
22
|
+
uv_gen = UVGenerator::Braindead.new fsm, archs
|
23
|
+
uv_gen.uv_pairs.to_a.should == [
|
24
|
+
[fsm0, Set[0,1], Set[]],
|
25
|
+
[fsm1, Set[1], Set[0]],
|
26
|
+
[fsm2, Set[0], Set[1]],
|
27
|
+
[fsm3, Set[], Set[0,1]],
|
28
|
+
]
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module ArtDecomp describe UVGenerator::Relevance do
|
2
|
+
|
3
|
+
context 'given a certain FSM and a Set of Archs' do
|
4
|
+
|
5
|
+
it 'should yield U and V combinations in a relevance-based order' do
|
6
|
+
fsm = mock FSM, :input_count => 6, :input_relevance => [0, 1, 2, nil, nil, nil, 3, 4, 5]
|
7
|
+
fsm.stub!(:expand_x).and_return fsm
|
8
|
+
archs = Set[Arch[3,1]]
|
9
|
+
uv_gen = UVGenerator::Relevance.new fsm, archs
|
10
|
+
uvs = uv_gen.uv_pairs.to_a
|
11
|
+
uvs.size.should == 42
|
12
|
+
uvs[0].should == [fsm, Set[0,1,2], Set[3,4,5]]
|
13
|
+
uvs[1].should == [fsm, Set[0,1,2,3], Set[4,5]]
|
14
|
+
uvs[2].should == [fsm, Set[0,1,2,4], Set[3,5]]
|
15
|
+
uvs[3].should == [fsm, Set[0,1,2,5], Set[3,4]]
|
16
|
+
uvs[4].should == [fsm, Set[0,1,2,3,4], Set[5]]
|
17
|
+
uvs[5].should == [fsm, Set[0,1,2,3,5], Set[4]]
|
18
|
+
uvs[6].should == [fsm, Set[0,1,2,4,5], Set[3]]
|
19
|
+
uvs[7].should == [fsm, Set[0,1,2,3,4,5], Set[]]
|
20
|
+
uvs[8].should == [fsm, Set[0,1,3], Set[2,4,5]]
|
21
|
+
uvs.last.should == [fsm, Set[3,4,5], Set[0,1,2]]
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should consider all architecture widths when generating the UV sets' do
|
25
|
+
fsm = mock FSM, :input_count => 6, :input_relevance => [0, 1, 2, nil, nil, nil, 3, 4, 5]
|
26
|
+
fsm.stub!(:expand_x).and_return fsm
|
27
|
+
archs = Set[Arch[3,1], Arch[2,1]]
|
28
|
+
uv_gen = UVGenerator::Relevance.new fsm, archs
|
29
|
+
uvs = uv_gen.uv_pairs.to_a
|
30
|
+
uvs.size.should == 42
|
31
|
+
uvs[0].should == [fsm, Set[0,1,2,3], Set[4,5]]
|
32
|
+
uvs[1].should == [fsm, Set[0,1,2,4], Set[3,5]]
|
33
|
+
uvs[2].should == [fsm, Set[0,1,2,5], Set[3,4]]
|
34
|
+
uvs[3].should == [fsm, Set[0,1,2], Set[3,4,5]]
|
35
|
+
uvs[4].should == [fsm, Set[0,1,2,3,4], Set[5]]
|
36
|
+
uvs[5].should == [fsm, Set[0,1,2,3,5], Set[4]]
|
37
|
+
uvs[6].should == [fsm, Set[0,1,2,4,5], Set[3]]
|
38
|
+
uvs[7].should == [fsm, Set[0,1,2,3,4,5], Set[]]
|
39
|
+
uvs[8].should == [fsm, Set[0,1,3,4], Set[2,5]]
|
40
|
+
uvs[9].should == [fsm, Set[0,1,3,5], Set[2,4]]
|
41
|
+
uvs[10].should == [fsm, Set[0,1,3], Set[2,4,5]]
|
42
|
+
uvs.last.should == [fsm, Set[3,4,5], Set[0,1,2]]
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should yield V-expanded FSMs' do
|
46
|
+
fsm = mock FSM, :input_count => 2, :input_relevance => [1, 0, nil, nil, nil]
|
47
|
+
fsm0, fsm1, fsm2, fsm3 = mock(FSM), mock(FSM), mock(FSM), mock(FSM)
|
48
|
+
fsm.should_receive(:expand_x).exactly(4).times.and_return(fsm0, fsm1, fsm2, fsm3)
|
49
|
+
archs = Set[Arch[3,1]]
|
50
|
+
uv_gen = UVGenerator::Relevance.new fsm, archs
|
51
|
+
uv_gen.uv_pairs.to_a.should == [
|
52
|
+
[fsm0, Set[0,1], Set[]],
|
53
|
+
[fsm1, Set[1], Set[0]],
|
54
|
+
[fsm2, Set[0], Set[1]],
|
55
|
+
[fsm3, Set[], Set[0,1]],
|
56
|
+
]
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
describe Enumerable do
|
2
|
+
|
3
|
+
it 'should provide an Enumerator for consecutive element pairs' do
|
4
|
+
set = Set[1,2,3,4]
|
5
|
+
set.pairs.to_a.should == [[1,2], [1,3], [1,4], [2,3], [2,4], [3,4]]
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should fall back to #combination for the pair selection if possible' do
|
9
|
+
array = [1,2,3,4]
|
10
|
+
array.should_receive(:combination).with 2
|
11
|
+
array.pairs
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should have a method to get all possible combinations of the passed elements' do
|
15
|
+
source = [[:a,:b], [:c], [:d,:e,:f]]
|
16
|
+
Enumerable.all_combinations(source).should == [[:a,:c,:d], [:a,:c,:e], [:a,:c,:f],
|
17
|
+
[:b,:c,:d], [:b,:c,:e], [:b,:c,:f]]
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
describe File do
|
2
|
+
|
3
|
+
it 'should be able to marshal an object to a given file' do
|
4
|
+
file = Tempfile.new rand
|
5
|
+
File.dump_object [:answer, 42, 'Deep Thought'], file.path
|
6
|
+
Marshal.load(File.read(file.path)).should == [:answer, 42, 'Deep Thought']
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should be able to dump arbitrary data to a given file' do
|
10
|
+
file = Tempfile.new rand
|
11
|
+
File.write_data '42', file.path
|
12
|
+
File.read(file.path).should == '42'
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
describe Integer do
|
2
|
+
|
3
|
+
it 'should return set bits' do
|
4
|
+
0.bits.should == []
|
5
|
+
0b111.bits.should == [0,1,2]
|
6
|
+
0b1000.bits.should == [3]
|
7
|
+
0b101010.bits.should == [1,3,5]
|
8
|
+
(2**69).bits.should == [69]
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should return ceil of base-2 logarithm' do
|
12
|
+
(0..9).map(&:log2_ceil).should == [0,0,1,2,2,3,3,3,3,4]
|
13
|
+
(2**69).log2_ceil.should == 69
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
describe Set do
|
4
|
+
|
5
|
+
it 'should side-step a MRI bug with Set#hash' do
|
6
|
+
Set[2305860601668175887].hash.should == Set[2305860601668175887].hash
|
7
|
+
end
|
8
|
+
|
9
|
+
context 'of Separations' do
|
10
|
+
|
11
|
+
B, Sep = ArtDecomp::B, ArtDecomp::Sep
|
12
|
+
|
13
|
+
it 'should provide a given block’s r-admissibility' do
|
14
|
+
b = B[1,2,3,4]
|
15
|
+
Set[Sep[1,5]].r_adm(b).should == 0
|
16
|
+
Set[Sep[1,4]].r_adm(b).should == 1
|
17
|
+
Set[Sep[1,2], Sep[5,6]].r_adm(b).should == 1
|
18
|
+
Set[Sep[1,2], Sep[3,4]].r_adm(b).should == 1
|
19
|
+
Set[Sep[1,3], Sep[1,4], Sep[2,3], Sep[2,4]].r_adm(b).should == 1
|
20
|
+
Set[Sep[1,3], Sep[1,4], Sep[2,3], Sep[2,4], Sep[3,4]].r_adm(b).should == 2
|
21
|
+
ArtDecomp::Blanket[B[1],B[2],B[3],B[4]].seps.r_adm(b).should == 2
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
describe String do
|
4
|
+
|
5
|
+
it 'should provide an expansion of don’t-cares when representing boolean inputs' do
|
6
|
+
'0'.dc_expand.should == ['0']
|
7
|
+
'-'.dc_expand.should == ['0', '1']
|
8
|
+
'-1-'.dc_expand.should == ['010', '011', '110', '111']
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'the expansion should be limitable to just a given set of columns' do
|
12
|
+
'---'.dc_expand.should == ['000', '001', '010', '011', '100', '101', '110', '111']
|
13
|
+
'---'.dc_expand(Set[0,2]).should == ['0-0', '0-1', '1-0', '1-1']
|
14
|
+
'---'.dc_expand(Set[1]).should == ['-0-', '-1-']
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
data/spec/fixtures/ex5
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
.i 2
|
2
|
+
.o 2
|
3
|
+
.p 32
|
4
|
+
.s 9
|
5
|
+
00 1 0 --
|
6
|
+
01 1 7 00
|
7
|
+
10 1 5 11
|
8
|
+
11 1 4 --
|
9
|
+
00 2 1 --
|
10
|
+
01 2 4 --
|
11
|
+
10 2 0 --
|
12
|
+
11 2 0 00
|
13
|
+
00 3 3 --
|
14
|
+
01 3 0 00
|
15
|
+
10 3 0 --
|
16
|
+
11 3 7 11
|
17
|
+
00 4 5 00
|
18
|
+
01 4 0 --
|
19
|
+
10 4 1 --
|
20
|
+
11 4 0 --
|
21
|
+
00 5 0 11
|
22
|
+
01 5 6 --
|
23
|
+
10 5 0 11
|
24
|
+
11 5 0 11
|
25
|
+
00 6 0 11
|
26
|
+
01 6 5 --
|
27
|
+
10 6 1 11
|
28
|
+
11 6 0 11
|
29
|
+
00 7 6 --
|
30
|
+
01 7 0 11
|
31
|
+
10 7 2 --
|
32
|
+
11 7 8 --
|
33
|
+
00 8 3 --
|
34
|
+
01 8 0 --
|
35
|
+
10 8 1 00
|
36
|
+
11 8 0 --
|
data/spec/fixtures/fsm
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
.i 4
|
2
|
+
.o 2
|
3
|
+
.p 20
|
4
|
+
.s 10
|
5
|
+
--00 init0 init1 00
|
6
|
+
0100 init1 init1 00
|
7
|
+
--1- init1 init2 10
|
8
|
+
1-10 init2 init4 10
|
9
|
+
-111 init4 init4 10
|
10
|
+
--01 init4 IOwait 01
|
11
|
+
000- IOwait IOwait 01
|
12
|
+
100- IOwait init1 01
|
13
|
+
0110 IOwait read0 00
|
14
|
+
1100 IOwait write0 11
|
15
|
+
0111 IOwait RMACK 11
|
16
|
+
1101 IOwait WMACK 00
|
17
|
+
-01- IOwait init2 01
|
18
|
+
0010 RMACK RMACK 11
|
19
|
+
0111 RMACK read0 00
|
20
|
+
1100 WMACK WMACK 00
|
21
|
+
1001 WMACK write0 01
|
22
|
+
0001 read0 read1 11
|
23
|
+
0010 read1 IOwait 01
|
24
|
+
0100 write0 IOwait 01
|
@@ -0,0 +1,40 @@
|
|
1
|
+
0000 IOwait IOwait 01
|
2
|
+
0000 init0 init1 00
|
3
|
+
0001 IOwait IOwait 01
|
4
|
+
0001 init4 IOwait 01
|
5
|
+
0001 read0 read1 11
|
6
|
+
0010 IOwait init2 01
|
7
|
+
0010 RMACK RMACK 11
|
8
|
+
0010 init1 init2 10
|
9
|
+
0010 read1 IOwait 01
|
10
|
+
0011 IOwait init2 01
|
11
|
+
0011 init1 init2 10
|
12
|
+
0100 init0 init1 00
|
13
|
+
0100 init1 init1 00
|
14
|
+
0100 write0 IOwait 01
|
15
|
+
0101 init4 IOwait 01
|
16
|
+
0110 IOwait read0 00
|
17
|
+
0110 init1 init2 10
|
18
|
+
0111 IOwait RMACK 11
|
19
|
+
0111 RMACK read0 00
|
20
|
+
0111 init1 init2 10
|
21
|
+
0111 init4 init4 10
|
22
|
+
1000 IOwait init1 01
|
23
|
+
1000 init0 init1 00
|
24
|
+
1001 IOwait init1 01
|
25
|
+
1001 WMACK write0 01
|
26
|
+
1001 init4 IOwait 01
|
27
|
+
1010 IOwait init2 01
|
28
|
+
1010 init1 init2 10
|
29
|
+
1010 init2 init4 10
|
30
|
+
1011 IOwait init2 01
|
31
|
+
1011 init1 init2 10
|
32
|
+
1100 IOwait write0 11
|
33
|
+
1100 WMACK WMACK 00
|
34
|
+
1100 init0 init1 00
|
35
|
+
1101 IOwait WMACK 00
|
36
|
+
1101 init4 IOwait 01
|
37
|
+
1110 init1 init2 10
|
38
|
+
1110 init2 init4 10
|
39
|
+
1111 init1 init2 10
|
40
|
+
1111 init4 init4 10
|
data/spec/fixtures/fsm.f
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
--00 init0 init1 00
|
2
|
+
--01 init4 IOwait 01
|
3
|
+
--1- init1 init2 10
|
4
|
+
-01- IOwait init2 01
|
5
|
+
-111 init4 init4 10
|
6
|
+
000- IOwait IOwait 01
|
7
|
+
0001 read0 read1 11
|
8
|
+
0010 RMACK RMACK 11
|
9
|
+
0010 read1 IOwait 01
|
10
|
+
0100 init1 init1 00
|
11
|
+
0100 write0 IOwait 01
|
12
|
+
0110 IOwait read0 00
|
13
|
+
0111 IOwait RMACK 11
|
14
|
+
0111 RMACK read0 00
|
15
|
+
1-10 init2 init4 10
|
16
|
+
100- IOwait init1 01
|
17
|
+
1001 WMACK write0 01
|
18
|
+
1100 IOwait write0 11
|
19
|
+
1100 WMACK WMACK 00
|
20
|
+
1101 IOwait WMACK 00
|
data/spec/fixtures/fsm.g
ADDED