gecoder 0.2.0 → 0.3.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/CHANGES ADDED
@@ -0,0 +1,21 @@
1
+ == Version 0.3.0
2
+
3
+ * The constructor of Gecode::Model no longer has to be called by classes inheriting from it.
4
+ * Added Model#reset! which resets a model after search.
5
+ * Added Model#solution which passes the first solution to a block and returns the result of that block.
6
+ * Added Model#each_soltion which iterates over each solution.
7
+ * Added boolean variables. They are created using Model#bool_var and Model#bool_var_array .
8
+ * Added two options to constraints: propagation strength and reification variable.
9
+ * Linear and simple relation constraints can now also be specified using #equal, #equal_to, #greater, #greater_than,... in addition to comparison operators.
10
+ * Added distinct with offsets.
11
+ * Simple relation constraints can now be used to specify relations between two variables.
12
+ * Added basic boolean domain constraints along with conjunction and disjunction.
13
+ * Added syntactic sugar for combining reifiable constraints with | and &.
14
+
15
+ == Version 0.2.0
16
+
17
+ This is the first release of Gecode/R, a Ruby interface to Gecode.
18
+
19
+ * Added support for finite domain integers.
20
+ * Added some basic relation, linear and distinct constraints.
21
+ * Added the basis needed to model problems and find the first solution.
data/README CHANGED
@@ -3,6 +3,14 @@
3
3
  Gecode/R is a Ruby interface to Gecode, an open, free and efficient environment
4
4
  for developing constraint-based systems and applications.
5
5
 
6
+ == Warning
7
+
8
+ Gecode/R is still in an early development stage, the syntax is by no means
9
+ final and backwards compatibility will be broken time and time again until
10
+ later in the development process. Don’t use Gecode/R in production-code yet,
11
+ it’s merely available this early to allow people to play with it and give
12
+ feedback.
13
+
6
14
  == Installation
7
15
 
8
16
  Gecode/R requires Gecode 1.3.1, which can be downloaded from
@@ -17,4 +25,4 @@ instructions.
17
25
  === Building the gem
18
26
 
19
27
  rake gem
20
- gem install pkg/gecoder-0.x.gem
28
+ gem install pkg/gecoder-0.x.x.gem
data/ext/missing.cpp CHANGED
@@ -152,7 +152,7 @@ MSpace::MSpace(MSpace& s, bool share) : Gecode::Space(share, s), d(new Private)
152
152
 
153
153
  for(it = s.d->boolArrays.begin(); it != eend; it++)
154
154
  {
155
- Gecode::MBoolVarArray *bva = new Gecode::MBoolVarArray;
155
+ Gecode::MBoolVarArray *bva = new Gecode::MBoolVarArray(this, (*it).second->ptr()->size());
156
156
 
157
157
  bva->ptr()->update(this, share, *(*it).second->ptr() );
158
158
 
data/ext/vararray.cpp CHANGED
@@ -164,6 +164,10 @@ MBoolVarArray::MBoolVarArray(const Gecode::BoolVarArray &arr) : d(new Private)
164
164
  setSize(arr.size());
165
165
  setCount(0);
166
166
  }
167
+ MBoolVarArray::MBoolVarArray (Space *home, int n) : d(new Private)
168
+ {
169
+ setArray(Gecode::BoolVarArray(home, n));
170
+ }
167
171
 
168
172
  MBoolVarArray::~MBoolVarArray()
169
173
  {
data/ext/vararray.h CHANGED
@@ -83,7 +83,8 @@ class MBoolVarArray : public MVarArray
83
83
  public:
84
84
  MBoolVarArray();
85
85
  MBoolVarArray(const Gecode::BoolVarArray &arr);
86
-
86
+ MBoolVarArray(Space *home, int n);
87
+
87
88
  ~MBoolVarArray();
88
89
 
89
90
  void enlargeArray(Gecode::Space *parent, int n = 1);
@@ -188,6 +188,11 @@ Rust::Bindings::create_bindings Rust::Bindings::LangCxx, "gecode" do |b|
188
188
  ns.add_cxx_class "MBoolVarArray" do |klass|
189
189
  klass.bindname = "BoolVarArray"
190
190
  klass.add_constructor
191
+ klass.add_constructor do |func|
192
+ func.add_parameter "Gecode::MSpace *", "home"
193
+ func.add_parameter "int", "n"
194
+ end
195
+
191
196
  klass.add_method "at", "Gecode::BoolVar&" do |method|
192
197
  method.add_parameter "int", "index"
193
198
  end
@@ -195,6 +200,11 @@ Rust::Bindings::create_bindings Rust::Bindings::LangCxx, "gecode" do |b|
195
200
  klass.add_operator "[]", "Gecode::BoolVar&" do |method|
196
201
  method.add_parameter "int", "index"
197
202
  end
203
+
204
+ klass.add_operator "[]=", "Gecode::BoolVar&" do |method|
205
+ method.add_parameter "int", "index"
206
+ method.add_parameter "Gecode::BoolVar", "val"
207
+ end
198
208
 
199
209
  klass.add_method "size", "int"
200
210
 
@@ -428,6 +438,22 @@ Rust::Bindings::create_bindings Rust::Bindings::LangCxx, "gecode" do |b|
428
438
  klass.add_constructor do |method|
429
439
  method.add_parameter "Gecode::IntVar", "x"
430
440
  end
441
+
442
+ klass.add_method "max", "int"
443
+
444
+ klass.add_method "min", "int"
445
+ klass.add_method "med", "int"
446
+ klass.add_method "val", "int"
447
+ klass.add_method "size", "unsigned int"
448
+ klass.add_method "width", "unsigned int"
449
+ klass.add_method "degree", "unsigned int"
450
+
451
+ klass.add_method "range", "bool"
452
+ klass.add_method "assigned", "bool"
453
+ klass.add_method "in", "bool" do |method|
454
+ method.add_parameter "int", "n"
455
+ end
456
+
431
457
  klass.add_method "update", "void" do |method|
432
458
  method.add_parameter "Gecode::MSpace*", "home"
433
459
  method.add_parameter "bool", "share"
@@ -545,6 +571,12 @@ Rust::Bindings::create_bindings Rust::Bindings::LangCxx, "gecode" do |b|
545
571
  method.add_parameter "Gecode::IntRelType", "irt"
546
572
  method.add_parameter "Gecode::IntConLevel", "icl"
547
573
  end
574
+
575
+ klass.add_method "post" do |method|
576
+ method.add_parameter "Gecode::MSpace *", "home"
577
+ method.add_parameter "Gecode::IntRelType", "irt"
578
+ method.add_parameter "Gecode::BoolVar", "b"
579
+ end
548
580
 
549
581
  klass.add_operator "+", "Gecode::MiniModel::LinExpr" do |operator|
550
582
  operator.add_parameter("Gecode::MiniModel::LinExpr", "exp")
@@ -597,17 +629,17 @@ Rust::Bindings::create_bindings Rust::Bindings::LangCxx, "gecode" do |b|
597
629
  klass.add_constructor do |method|
598
630
  method.add_parameter "Gecode::MiniModel::BoolExpr", "e"
599
631
  end
600
-
632
+
633
+ klass.add_constructor do |method|
634
+ method.add_parameter "Gecode::BoolVar", "e"
635
+ end
636
+
601
637
  klass.add_constructor do |method|
602
638
  method.add_parameter "Gecode::MiniModel::BoolExpr", "l"
603
639
  method.add_parameter "Gecode::MiniModel::BoolExpr::NodeType", "t"
604
640
  method.add_parameter "Gecode::MiniModel::BoolExpr", "r"
605
641
  end
606
642
 
607
- klass.add_constructor do |method|
608
- method.add_parameter "Gecode::BoolVar", "e"
609
- end
610
-
611
643
  klass.add_constructor do |method|
612
644
  method.add_parameter "Gecode::MiniModel::BoolExpr", "l"
613
645
  method.add_parameter "Gecode::MiniModel::BoolExpr::NodeType", "t"
@@ -616,6 +648,15 @@ Rust::Bindings::create_bindings Rust::Bindings::LangCxx, "gecode" do |b|
616
648
  klass.add_constructor do |method|
617
649
  method.add_parameter "Gecode::MiniModel::LinRel", "e"
618
650
  end
651
+
652
+ klass.add_method "post" do |method|
653
+ method.add_parameter "Gecode::MSpace *", "home"
654
+ end
655
+
656
+ klass.add_method "post" do |method|
657
+ method.add_parameter "Gecode::MSpace *", "home"
658
+ method.add_parameter "bool", "t"
659
+ end
619
660
  end
620
661
 
621
662
  minimodelns.add_cxx_class "BoolRel" do |klass|
@@ -857,6 +898,15 @@ Rust::Bindings::create_bindings Rust::Bindings::LangCxx, "gecode" do |b|
857
898
  func.add_parameter "Gecode::BvarSel", "vars"
858
899
  func.add_parameter "Gecode::BvalSel", "vals"
859
900
  end
901
+
902
+ ns.add_function "branch" do |func|
903
+ func.add_parameter "Gecode::MSpace *", "home"
904
+ func.add_parameter "Gecode::MBoolVarArray *", "iva" do |param|
905
+ param.custom_conversion = "*ruby2Gecode_MBoolVarArrayPtr(argv[1], 2)->ptr()"
906
+ end
907
+ func.add_parameter "Gecode::BvarSel", "vars"
908
+ func.add_parameter "Gecode::BvalSel", "vals"
909
+ end
860
910
 
861
911
  ns.add_function "branch" do |func|
862
912
  func.add_parameter "Gecode::MSpace *", "home"
@@ -1,4 +1,5 @@
1
1
  require 'gecoder/interface/binding_changes'
2
+ require 'gecoder/interface/variables'
2
3
  require 'gecoder/interface/model'
3
4
  require 'gecoder/interface/search'
4
5
  require 'gecoder/interface/constraints'
@@ -6,106 +6,208 @@
6
6
  #
7
7
  # This layer should be moved to the C++ side instead when possible for better
8
8
  # performance.
9
- module Gecode::Raw
10
- class Space
11
- # Creates the specified number of integer variables in the store. Returns
12
- # the indices with which they can then be accessed using int_var.
13
- def new_int_vars(min, max, count = 1)
14
- int_var_store.new_vars(min, max, count)
9
+ module Gecode
10
+ module Raw
11
+ class Space
12
+ # Creates the specified number of integer variables in the space. Returns
13
+ # the indices with which they can then be accessed using int_var.
14
+ def new_int_vars(min, max, count = 1)
15
+ int_var_store.new_vars(min, max, count)
16
+ end
17
+
18
+ # Gets the int variable with the specified index, nil if none exists.
19
+ def int_var(index)
20
+ int_var_store[index]
21
+ end
22
+
23
+ # Creates the specified number of boolean variables in the space. Returns
24
+ # the indices with which they can then be accessed using int_var.
25
+ def new_bool_vars(count = 1)
26
+ bool_var_store.new_vars(count)
27
+ end
28
+
29
+ # Gets the int variable with the specified index, nil if none exists.
30
+ def bool_var(index)
31
+ bool_var_store[index]
32
+ end
33
+
34
+ private
35
+
36
+ # Retrieves the store used for integer variables. Creates one if none
37
+ # exists.
38
+ def int_var_store
39
+ if @int_var_store.nil?
40
+ @int_var_store = Gecode::Util::IntVarStore.new(self)
41
+ end
42
+ return @int_var_store
43
+ end
44
+
45
+ # Retrieves the store used for boolean variables. Creates one if none
46
+ # exists.
47
+ def bool_var_store
48
+ if @bool_var_store.nil?
49
+ @bool_var_store = Gecode::Util::BoolVarStore.new(self)
50
+ end
51
+ return @bool_var_store
52
+ end
15
53
  end
16
54
 
17
- # Gets the int variable with the specified index, nil if none exists.
18
- def int_var(index)
19
- int_var_store[index]
55
+ class IntVar
56
+ # Aliases to make method-names more ruby-like.
57
+ alias_method :assigned?, :assigned
58
+ alias_method :in?, :in
59
+ alias_method :include?, :in
60
+ alias_method :range?, :range
20
61
  end
21
62
 
22
- private
23
-
24
- # Retrieves the store used for integer variables. Creates one if none
25
- # exists.
26
- def int_var_store
27
- if @int_var_store.nil?
28
- @int_var_store = Gecode::Raw::IntVarStore.new(self)
63
+ class BoolVar
64
+ # Aliases to make method-names more ruby-like.
65
+ alias_method :assigned?, :assigned
66
+
67
+ def true?
68
+ val == 1
29
69
  end
30
- return @int_var_store
31
70
  end
32
71
  end
33
-
34
- # A store in which int variables are created and stored.
35
- class IntVarStore
36
- # Design note: The store used to double its size when it needed to grow
37
- # leaving unallocated slots (in rev 16). This was changed to only growing
38
- # the amount of space needed because the additional information about which
39
- # slot is the next unallocated one could not be encoded without changes to
40
- # the bindings (and without that information we can not deduce the store
41
- # from the new copy of space). So for additional performance the bindings
42
- # should grow the array more than needed (when this is moved to the bindings).
43
-
44
- private
45
72
 
46
- # A string that identifies the array used by the store.
47
- ARRAY_IDENTIFIER = 'int_array'
73
+ # Various utility (mainly used to change the behavior of the raw bindings).
74
+ module Util
75
+ # Provides common methods to the variable stores. The stores must provide
76
+ # @next_index, @var_array, @size, ARRAY_IDENTIFIER and #new_storage_array .
77
+ module VarStoreMethods
78
+ # Returns the int var with the specified index, nil if none exists.
79
+ def [](index)
80
+ if index < 0 or index >= @next_index
81
+ return nil
82
+ end
83
+ return @var_array.at(index)
84
+ end
85
+
86
+ private
87
+
88
+ # Grows the store to the new size.
89
+ def grow(new_size)
90
+ new_array = new_storage_array(new_size)
91
+ @var_array.size.times do |i|
92
+ new_array[i] = @var_array[i]
93
+ end
94
+ @var_array = new_array
95
+ @size = new_size
96
+ end
97
+ end
48
98
 
49
- public
99
+ # A store in which int variables are created and stored.
100
+ class IntVarStore
101
+ # Design note: The store used to double its size when it needed to grow
102
+ # leaving unallocated slots (in rev 16). This was changed to only growing
103
+ # the amount of space needed because the additional information about which
104
+ # slot is the next unallocated one could not be encoded without changes to
105
+ # the bindings (and without that information we can not deduce the store
106
+ # from the new copy of space). So for additional performance the bindings
107
+ # should grow the array more than needed (when this is moved to the bindings).
108
+
109
+ include VarStoreMethods
110
+
111
+ private
50
112
 
51
- # Creates a store for the specified space with the specified capacit.
52
- def initialize(space)
53
- @var_array = space.int_var_array(ARRAY_IDENTIFIER)
54
- if @var_array.nil?
55
- # Create a new one.
56
- @var_array = Gecode::Raw::IntVarArray.new(space, 0)
57
- space.own(@var_array, ARRAY_IDENTIFIER)
58
- end
59
-
60
- @size = @var_array.size
61
- @next_index = @size
62
- @space = space
63
- end
113
+ # A string that identifies the array used by the store.
114
+ ARRAY_IDENTIFIER = 'int_array'
64
115
 
65
- # Creates the specified number of new int variables with the specified
66
- # range as domain. Returns the indices of the created variables as an array.
67
- def new_vars(min, max, count = 1)
68
- grow(@next_index + count) # See the design note for more information.
69
- count.times do |i|
70
- @var_array[@next_index] = Gecode::Raw::IntVar.new(@space,
71
- min, max)
72
- @next_index += 1
116
+ public
117
+
118
+ # Creates a store for the specified space with the specified capacit.
119
+ def initialize(space)
120
+ @space = space
121
+
122
+ @var_array = space.int_var_array(ARRAY_IDENTIFIER)
123
+ if @var_array.nil?
124
+ # Create a new one.
125
+ @var_array = new_storage_array(0)
126
+ end
127
+
128
+ @size = @var_array.size
129
+ @next_index = @size
73
130
  end
74
131
 
75
- ((@next_index - count)...@next_index).to_a
76
- end
77
-
78
- # Returns the int var with the specified index, nil if none exists.
79
- def [](index)
80
- if index < 0 or index >= @next_index
81
- return nil
132
+ # Creates the specified number of new int variables with the specified
133
+ # range as domain. Returns the indices of the created variables as an array.
134
+ def new_vars(min, max, count = 1)
135
+ grow(@next_index + count) # See the design note for more information.
136
+ count.times do |i|
137
+ @var_array[@next_index] = Gecode::Raw::IntVar.new(@space,
138
+ min, max)
139
+ @next_index += 1
140
+ end
141
+
142
+ ((@next_index - count)...@next_index).to_a
143
+ end
144
+
145
+ # Returns the int var with the specified index, nil if none exists.
146
+ def [](index)
147
+ if index < 0 or index >= @next_index
148
+ return nil
149
+ end
150
+ return @var_array.at(index)
151
+ end
152
+
153
+ private
154
+
155
+ # Creates a new storage array for int variables.
156
+ def new_storage_array(new_size)
157
+ arr = Gecode::Raw::IntVarArray.new(@space, new_size)
158
+ @space.own(arr, ARRAY_IDENTIFIER)
159
+ return arr
82
160
  end
83
- return @var_array.at(index)
84
161
  end
85
-
86
- private
87
162
 
88
- # Grows the store to the new size.
89
- def grow(new_size)
90
- if new_size <= @size
91
- raise ArgumentError, 'New size must be larger than the old one.'
163
+ # A store in which int variables are created and stored.
164
+ class BoolVarStore
165
+ # TODO: can we refactor this better seeing as IntVarStore and BoolVarStore
166
+ # are similar?
167
+
168
+ include VarStoreMethods
169
+
170
+ private
171
+
172
+ # A string that identifies the array used by the store.
173
+ ARRAY_IDENTIFIER = 'bool_array'
174
+
175
+ public
176
+
177
+ # Creates a store for the specified space with the specified capacit.
178
+ def initialize(space)
179
+ @space = space
180
+
181
+ @var_array = space.bool_var_array(ARRAY_IDENTIFIER)
182
+ if @var_array.nil?
183
+ # Create a new one.
184
+ @var_array = new_storage_array(0)
185
+ end
186
+
187
+ @size = @var_array.size
188
+ @next_index = @size
92
189
  end
93
190
 
94
- new_array = Gecode::Raw::IntVarArray.new(@space, new_size)
95
- @var_array.size.times do |i|
96
- new_array[i] = @var_array[i]
191
+ # Creates the specified number of new bool variables. Returns the indices
192
+ # of the created variables as an array.
193
+ def new_vars(count = 1)
194
+ grow(@next_index + count) # See the design note for more information.
195
+ count.times do |i|
196
+ @var_array[@next_index] = Gecode::Raw::BoolVar.new(@space, 0, 1)
197
+ @next_index += 1
198
+ end
199
+
200
+ ((@next_index - count)...@next_index).to_a
97
201
  end
98
- @space.own(new_array, ARRAY_IDENTIFIER)
99
- @var_array = new_array
100
- @size = new_size
101
- end
102
- end
103
202
 
104
- class IntVar
105
- # Aliases to make method-names more ruby-like.
106
- alias_method :assigned?, :assigned
107
- alias_method :in?, :in
108
- alias_method :range?, :range
203
+ private
204
+
205
+ # Creates a new storage array for bool variables.
206
+ def new_storage_array(new_size)
207
+ arr = Gecode::Raw::BoolVarArray.new(@space, new_size)
208
+ @space.own(arr, ARRAY_IDENTIFIER)
209
+ return arr
210
+ end
211
+ end
109
212
  end
110
213
  end
111
-