art-decomp 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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