gecoder 0.2.0 → 0.3.0

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