cudd-rb 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. data/CHANGELOG.md +5 -0
  2. data/Gemfile +12 -0
  3. data/Gemfile.lock +26 -0
  4. data/LICENCE.md +22 -0
  5. data/Manifest.txt +15 -0
  6. data/README.md +7 -0
  7. data/Rakefile +11 -0
  8. data/cudd-rb.gemspec +188 -0
  9. data/cudd-rb.noespec +30 -0
  10. data/lib/cudd-rb/bdd.rb +68 -0
  11. data/lib/cudd-rb/cube.rb +94 -0
  12. data/lib/cudd-rb/errors.rb +4 -0
  13. data/lib/cudd-rb/interfaces/bdd.rb +334 -0
  14. data/lib/cudd-rb/interfaces/root.rb +35 -0
  15. data/lib/cudd-rb/loader.rb +1 -0
  16. data/lib/cudd-rb/manager.rb +78 -0
  17. data/lib/cudd-rb/version.rb +14 -0
  18. data/lib/cudd-rb/wrapper.rb +58 -0
  19. data/lib/cudd-rb.rb +46 -0
  20. data/spec/cube/test_equality.rb +22 -0
  21. data/spec/cube/test_hash.rb +34 -0
  22. data/spec/cube/test_new.rb +49 -0
  23. data/spec/cube/test_to_a012.rb +34 -0
  24. data/spec/cube/test_to_bdd.rb +42 -0
  25. data/spec/cube/test_to_cube.rb +18 -0
  26. data/spec/cube/test_to_dnf.rb +55 -0
  27. data/spec/cube/test_to_hash.rb +34 -0
  28. data/spec/cube/test_to_truths.rb +34 -0
  29. data/spec/cudd/test_manager.rb +35 -0
  30. data/spec/interfaces/bdd/test_and.rb +14 -0
  31. data/spec/interfaces/bdd/test_bdd2cube.rb +32 -0
  32. data/spec/interfaces/bdd/test_bdd2dnf.rb +39 -0
  33. data/spec/interfaces/bdd/test_cofactor.rb +44 -0
  34. data/spec/interfaces/bdd/test_cube.rb +61 -0
  35. data/spec/interfaces/bdd/test_cube2bdd.rb +22 -0
  36. data/spec/interfaces/bdd/test_each_cube.rb +79 -0
  37. data/spec/interfaces/bdd/test_eval.rb +76 -0
  38. data/spec/interfaces/bdd/test_exist.rb +24 -0
  39. data/spec/interfaces/bdd/test_forall.rb +24 -0
  40. data/spec/interfaces/bdd/test_is_complement.rb +26 -0
  41. data/spec/interfaces/bdd/test_ite.rb +18 -0
  42. data/spec/interfaces/bdd/test_ith_var.rb +34 -0
  43. data/spec/interfaces/bdd/test_ith_vars.rb +40 -0
  44. data/spec/interfaces/bdd/test_new_var.rb +36 -0
  45. data/spec/interfaces/bdd/test_new_vars.rb +45 -0
  46. data/spec/interfaces/bdd/test_not.rb +18 -0
  47. data/spec/interfaces/bdd/test_one.rb +26 -0
  48. data/spec/interfaces/bdd/test_one_cube.rb +35 -0
  49. data/spec/interfaces/bdd/test_or.rb +14 -0
  50. data/spec/interfaces/bdd/test_restrict.rb +26 -0
  51. data/spec/interfaces/bdd/test_satisfiable.rb +33 -0
  52. data/spec/interfaces/bdd/test_satisfied.rb +40 -0
  53. data/spec/interfaces/bdd/test_size.rb +33 -0
  54. data/spec/interfaces/bdd/test_support.rb +66 -0
  55. data/spec/interfaces/bdd/test_var_index.rb +26 -0
  56. data/spec/interfaces/bdd/test_var_name.rb +32 -0
  57. data/spec/interfaces/bdd/test_var_names.rb +25 -0
  58. data/spec/interfaces/bdd/test_zero.rb +26 -0
  59. data/spec/manager/test_interface.rb +49 -0
  60. data/spec/shared/a_bdd.rb +15 -0
  61. data/spec/spec_helper.rb +45 -0
  62. data/spec/test_cudd-rb.rb +8 -0
  63. data/spec/wrapper/test_assumptions.rb +28 -0
  64. data/tasks/gem.rake +73 -0
  65. data/tasks/spec_test.rake +71 -0
  66. data/tasks/unit_test.rake +76 -0
  67. data/tasks/yard.rake +51 -0
  68. metadata +218 -0
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ module Cudd
3
+ describe Cube, 'to_a012' do
4
+
5
+ subject{ c.to_a012 }
6
+
7
+ before{ x; y; z }
8
+
9
+ context 'on x' do
10
+ let(:c){ cube(x => true) }
11
+
12
+ it 'returns the expected bdd' do
13
+ subject.should eq([1, 2, 2])
14
+ end
15
+ end
16
+
17
+ context 'on !x' do
18
+ let(:c){ cube(x => false) }
19
+
20
+ it 'returns the expected bdd' do
21
+ subject.should eq([0, 2, 2])
22
+ end
23
+ end
24
+
25
+ context 'on x & y' do
26
+ let(:c){ cube(x => true, y => true) }
27
+
28
+ it 'returns the expected bdd' do
29
+ subject.should eq([1, 1, 2])
30
+ end
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+ module Cudd
3
+ describe Cube, 'to_bdd' do
4
+
5
+ subject{ c.to_bdd }
6
+
7
+ before{ x; y; z }
8
+
9
+ context 'on an empty cube' do
10
+ let(:c){ cube([]) }
11
+
12
+ it "returns ONE" do
13
+ subject.should eq(one)
14
+ end
15
+ end
16
+
17
+ context 'on x' do
18
+ let(:c){ cube(x => true) }
19
+
20
+ it 'returns the expected bdd' do
21
+ subject.should eq(x)
22
+ end
23
+ end
24
+
25
+ context 'on !x' do
26
+ let(:c){ cube(x => false) }
27
+
28
+ it 'returns the expected bdd' do
29
+ subject.should eq(!x)
30
+ end
31
+ end
32
+
33
+ context 'on x & y' do
34
+ let(:c){ cube(x => true, y => true) }
35
+
36
+ it 'returns the expected bdd' do
37
+ subject.should eq(x & y)
38
+ end
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+ module Cudd
3
+ describe Cube, 'to_cube' do
4
+
5
+ subject{ c.to_bdd }
6
+
7
+ before{ x; y; z }
8
+
9
+ context 'on x & y' do
10
+ let(:c){ cube(x => true, y => true) }
11
+
12
+ it 'returns itself' do
13
+ subject.should eq(subject)
14
+ end
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+ module Cudd
3
+ describe Cube, 'to_dnf' do
4
+
5
+ subject{ c.to_dnf }
6
+
7
+ before{ x; y; z }
8
+
9
+ context 'on singleton' do
10
+ let(:c){ cube(x => true) }
11
+
12
+ it 'uses default names' do
13
+ subject.should eq("v0")
14
+ end
15
+ end
16
+
17
+ context 'on negative singleton' do
18
+ let(:c){ cube(x => false) }
19
+
20
+ it 'uses default names' do
21
+ subject.should eq("!v0")
22
+ end
23
+ end
24
+
25
+ context 'on unnamed variables' do
26
+ let(:c){ cube(x => true, y => false) }
27
+
28
+ it 'uses default names' do
29
+ subject.should eq("v0 & !v1")
30
+ end
31
+ end
32
+
33
+ context 'on named variables' do
34
+ let(:u){ bdd_interface.new_var(:u) }
35
+ let(:v){ bdd_interface.new_var(:v) }
36
+ let(:c){ cube(u => true, v => false) }
37
+
38
+ it 'uses provided names' do
39
+ subject.should eq("u & !v")
40
+ end
41
+ end
42
+
43
+ context 'on variables that respond to to_dnf' do
44
+ let(:var){ Object.new }
45
+ let(:u){ bdd_interface.new_var(var) }
46
+ let(:c){ cube(u => true) }
47
+
48
+ it 'uses provided names' do
49
+ def var.to_dnf; "foo"; end
50
+ subject.should eq("foo")
51
+ end
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ module Cudd
3
+ describe Cube, 'to_hash' do
4
+
5
+ subject{ c.to_hash }
6
+
7
+ before{ x; y; z }
8
+
9
+ context 'on x' do
10
+ let(:c){ cube(x => true) }
11
+
12
+ it 'returns the expected bdd' do
13
+ subject.should eq(x => true)
14
+ end
15
+ end
16
+
17
+ context 'on !x' do
18
+ let(:c){ cube(x => false) }
19
+
20
+ it 'returns the expected bdd' do
21
+ subject.should eq(x => false)
22
+ end
23
+ end
24
+
25
+ context 'on x & y' do
26
+ let(:c){ cube(x => true, y => true) }
27
+
28
+ it 'returns the expected bdd' do
29
+ subject.should eq(x => true, y => true)
30
+ end
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ module Cudd
3
+ describe Cube, 'to_truths' do
4
+
5
+ subject{ c.to_truths }
6
+
7
+ before{ x; y; z }
8
+
9
+ context 'on x' do
10
+ let(:c){ cube(x => true) }
11
+
12
+ it 'returns the expected bdd' do
13
+ subject.should eq([true, nil, nil])
14
+ end
15
+ end
16
+
17
+ context 'on !x' do
18
+ let(:c){ cube(x => false) }
19
+
20
+ it 'returns the expected bdd' do
21
+ subject.should eq([false, nil, nil])
22
+ end
23
+ end
24
+
25
+ context 'on x & y' do
26
+ let(:c){ cube(x => true, y => true) }
27
+
28
+ it 'returns the expected bdd' do
29
+ subject.should eq([true, true, nil])
30
+ end
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+ module Cudd
3
+ describe ".manager" do
4
+
5
+ it 'passes the manager to the block, closes it afterwards and returns block result' do
6
+ manager = nil
7
+ result = Cudd.manager do |m|
8
+ manager = m
9
+ m.should be_a(Cudd::Manager)
10
+ m.should be_alive
11
+ m.should_not be_closed
12
+ 12
13
+ end
14
+ result.should eq(12)
15
+ manager.should_not be_alive
16
+ manager.should be_closed
17
+ end
18
+
19
+ it 'returns an alive manager if no block' do
20
+ begin
21
+ manager = Cudd.manager
22
+ manager.should be_alive
23
+ ensure
24
+ manager.close if manager
25
+ end
26
+ end
27
+
28
+ it 'sets options correctly' do
29
+ Cudd.manager :maxMemory => 10 do |m|
30
+ m.options[:maxMemory].should eq(10)
31
+ end
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+ module Cudd
3
+ describe Interface::BDD, 'and' do
4
+
5
+ subject{ bdd_interface.and(x,y) }
6
+
7
+ it_behaves_like "a BDD"
8
+
9
+ it 'is equal to (x & y)' do
10
+ subject.should eq(x & y)
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+ module Cudd
3
+ module Interfaces
4
+ describe BDD, "bdd2cube" do
5
+
6
+ before do
7
+ x; y; z
8
+ end
9
+
10
+ subject{ bdd_interface.bdd2cube(x & !y) }
11
+
12
+ it 'returns an Array' do
13
+ subject.should be_a(Array)
14
+ end
15
+
16
+ it 'encodes missing variables as well as explicit ones' do
17
+ subject.should eq([1, 0, 2])
18
+ end
19
+
20
+ it 'is available as BDD#to_cube' do
21
+ (x & !y).to_cube.should eq(subject)
22
+ end
23
+
24
+ it 'raises a NotACubeError on a BDD that is not a cube' do
25
+ lambda{
26
+ (x | y).to_cube
27
+ }.should raise_error(NotACubeError)
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+ module Cudd
3
+ module Interfaces
4
+ describe BDD, "bdd2dnf" do
5
+
6
+ before do
7
+ x; y; z
8
+ end
9
+
10
+ subject{ bdd.to_dnf }
11
+
12
+ context 'on ZERO' do
13
+ let(:bdd){ zero }
14
+ it{ should eq("false") }
15
+ end
16
+
17
+ context 'on ONE' do
18
+ let(:bdd){ one }
19
+ it{ should eq("true") }
20
+ end
21
+
22
+ context 'on an unnamed variable' do
23
+ let(:bdd){ x }
24
+ it{ should eq("v0") }
25
+ end
26
+
27
+ context 'on an named variable' do
28
+ let(:bdd){ bdd_interface.new_var(:foo) }
29
+ it{ should eq("foo") }
30
+ end
31
+
32
+ context 'on an complex formula' do
33
+ let(:bdd){ (x | y) & z }
34
+ it{ should eq("(!v0 & v1 & v2) | (v0 & v2)") }
35
+ end
36
+
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+ module Cudd
3
+ describe Interface::BDD, 'cofactor' do
4
+
5
+ subject{ (x & y).cofactor(cube) }
6
+
7
+ context 'with x as cube' do
8
+ let(:cube){ x }
9
+
10
+ it_behaves_like "a BDD"
11
+
12
+ it{ should eq(y) }
13
+ end
14
+
15
+ context 'with !x as cube' do
16
+ let(:cube){ !x }
17
+
18
+ it_behaves_like "a BDD"
19
+
20
+ it{ should eq(zero) }
21
+ end
22
+
23
+ context 'with a {x => true} as cube' do
24
+ let(:cube){ { x => true } }
25
+
26
+ it_behaves_like "a BDD"
27
+
28
+ it{ should eq(y) }
29
+ end
30
+
31
+ context 'when it is a complex bdd' do
32
+ let(:cube){ x.xor(y) }
33
+
34
+ it 'should raise a NotACubeError' do
35
+ pending{
36
+ lambda{
37
+ subject
38
+ }.should raise_error(NotACubeError)
39
+ }
40
+ end
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+ module Cudd
3
+ module Interfaces
4
+ describe BDD, "cube" do
5
+
6
+ before do
7
+ x; y; z
8
+ end
9
+
10
+ subject{ cube(arg, as) }
11
+
12
+ describe "as => :012" do
13
+ let(:as){ :a012 }
14
+
15
+ context 'when already a cube' do
16
+ let(:arg){ [ 1, 0, 2 ] }
17
+ it { should eq([ 1, 0, 2 ]) }
18
+ end
19
+
20
+ context 'when an incomplete cube' do
21
+ let(:arg){ [ 1, 0 ] }
22
+ it { should eq([ 1, 0, 2 ]) }
23
+ end
24
+
25
+ context 'when truth values' do
26
+ let(:arg){ [ true, false, nil ] }
27
+ it { should eq([ 1, 0, 2 ]) }
28
+ end
29
+
30
+ context 'when an array of BDD variables' do
31
+ let(:arg){ [!y, x] }
32
+ it { should eq([ 1, 0, 2 ]) }
33
+ end
34
+
35
+ context 'when a Hash' do
36
+ let(:arg){ {x => 1, y => false} }
37
+ it { should eq([ 1, 0, 2 ]) }
38
+ end
39
+ end
40
+
41
+ describe 'as => :bdd' do
42
+ let(:as){ :bdd }
43
+
44
+ context 'when an array of BDD variables' do
45
+ let(:arg){ [!y, x] }
46
+ it { should eq(x & !y) }
47
+ end
48
+ end
49
+
50
+ describe 'as => :hash' do
51
+ let(:as){ :hash }
52
+
53
+ context 'when an array of BDD variables' do
54
+ let(:arg){ [!y, x] }
55
+ it { should eq(x => true, y => false) }
56
+ end
57
+ end
58
+
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+ module Cudd
3
+ module Interfaces
4
+ describe BDD, "cube2bdd" do
5
+
6
+ before do
7
+ x; y; z
8
+ end
9
+
10
+ subject{ bdd_interface.cube2bdd([1, 0, 2]) }
11
+
12
+ it 'returns a BDD' do
13
+ subject.should be_a(Cudd::BDD)
14
+ end
15
+
16
+ it 'support 1, 0 and 2' do
17
+ subject.should eq(x & !y)
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,79 @@
1
+ require 'spec_helper'
2
+ module Cudd
3
+ module Interfaces
4
+ describe BDD, "each_cube" do
5
+
6
+ subject{ formula.all_cubes } # formula.each_cube.to_a
7
+
8
+ before do
9
+ x; y; z;
10
+ formula.ref
11
+ end
12
+
13
+ after do
14
+ subject.each do |cube|
15
+ cube.should be_a(Cube)
16
+ formula.satisfied?(cube).should be_true
17
+ end
18
+ formula.deref if formula
19
+ end
20
+
21
+ context 'without a block' do
22
+ let(:formula){ x & y }
23
+
24
+ it 'returns an enumerator' do
25
+ formula.each_cube.should be_a(Enumerator)
26
+ end
27
+ end
28
+
29
+ context "on ZERO" do
30
+ let(:formula){ zero }
31
+
32
+ it 'yields no assignment' do
33
+ subject.should be_empty
34
+ end
35
+ end
36
+
37
+ context "on ONE" do
38
+ let(:formula){ one }
39
+
40
+ it 'yields one empty assignment' do
41
+ subject.should eq([cube([2,2,2])])
42
+ end
43
+ end
44
+
45
+ context "on x" do
46
+ let(:formula){ x }
47
+
48
+ it 'yields one assignment with x=true' do
49
+ subject.should eq([cube([1,2,2])])
50
+ end
51
+ end
52
+
53
+ context "on !x" do
54
+ let(:formula){ !x }
55
+
56
+ it 'yields one assignment with x=false' do
57
+ subject.should eq([cube([0,2,2])])
58
+ end
59
+ end
60
+
61
+ context 'on (x & y)' do
62
+ let(:formula){ x & y }
63
+
64
+ it 'returns one assignment with both x and y to true' do
65
+ subject.should eq([cube([1,1,2])])
66
+ end
67
+ end
68
+
69
+ context 'on (x | y)' do
70
+ let(:formula){ x | y }
71
+
72
+ it 'returns two assignments' do
73
+ subject.should eq([cube([0,1,2]), cube([1,2,2])])
74
+ end
75
+ end
76
+
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+ module Cudd
3
+ describe Interface::BDD, 'eval' do
4
+
5
+ subject{ bdd_interface.eval(formula, input) }
6
+
7
+ context 'on one' do
8
+ let(:formula){ one }
9
+ let(:input){ [] }
10
+
11
+ it 'is always satisfied' do
12
+ subject.should eq(one)
13
+ end
14
+ end
15
+
16
+ context 'on zero' do
17
+ let(:formula){ zero }
18
+ let(:input){ [] }
19
+
20
+ it 'is never satisfied' do
21
+ subject.should eq(zero)
22
+ end
23
+ end
24
+
25
+ context 'on (x & y) with satisfying input' do
26
+ let(:formula){ bdd_interface.and(x, y) }
27
+ let(:input){ [ 1, 1 ] }
28
+
29
+ it 'is satisfied' do
30
+ subject.should eq(one)
31
+ end
32
+ end
33
+
34
+ context 'on (x & y) with non satisfying input' do
35
+ let(:formula){ bdd_interface.and(x, y) }
36
+ let(:input){ [ 1, 0 ] }
37
+
38
+ it 'is not satisfied' do
39
+ subject.should eq(zero)
40
+ end
41
+ end
42
+
43
+ context 'on a non-satisfying Hash input' do
44
+ let(:formula){ bdd_interface.and(x, y) }
45
+ let(:input){ {x => 1, y => 0} }
46
+
47
+ it 'is not satisfied' do
48
+ subject.should eq(zero)
49
+ end
50
+ end
51
+
52
+ context 'on a satisfying Hash input' do
53
+ let(:formula){ bdd_interface.and(x, y) }
54
+ let(:input){ {x => 1, y => 1} }
55
+
56
+ it 'is satisfied' do
57
+ subject.should eq(one)
58
+ end
59
+ end
60
+
61
+ context 'on invalid input' do
62
+ let(:input){ [ ] }
63
+
64
+ it 'complements input with missing 2' do
65
+ bdd_interface.eval(x, input).should eq(zero)
66
+ bdd_interface.eval(!x, input).should eq(one)
67
+ end
68
+ end
69
+
70
+ it 'is accessible as BDD#eval' do
71
+ (x & y).eval([1, 1]).should eq(one)
72
+ (x & y).eval([1, 0]).should eq(zero)
73
+ end
74
+
75
+ end
76
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ module Cudd
3
+ describe Interface::BDD, 'exist' do
4
+
5
+ subject{ (x & y).exist(g) }
6
+
7
+ context 'when g is a Hash' do
8
+ let(:g){ {x => true} }
9
+
10
+ it_behaves_like "a BDD"
11
+
12
+ it{ should eq(y) }
13
+ end
14
+
15
+ context 'when g is a cube bdd' do
16
+ let(:g){ x }
17
+
18
+ it_behaves_like "a BDD"
19
+
20
+ it { should eq(y) }
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ module Cudd
3
+ describe Interface::BDD, 'forall' do
4
+
5
+ subject{ (x | y).forall(g) }
6
+
7
+ context 'when g is a Hash' do
8
+ let(:g){ {x => true} }
9
+
10
+ it_behaves_like "a BDD"
11
+
12
+ it{ should eq(y) }
13
+ end
14
+
15
+ context 'when g is a cube bdd' do
16
+ let(:g){ x }
17
+
18
+ it_behaves_like "a BDD"
19
+
20
+ it { should eq(y) }
21
+ end
22
+
23
+ end
24
+ end