cudd-rb 0.0.1

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.
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