gecoder-with-gecode 0.8.3 → 0.9.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 +15 -0
- data/README +6 -2
- data/example/equation_system.rb +15 -0
- data/example/magic_sequence.rb +7 -7
- data/example/money.rb +36 -0
- data/example/queens.rb +7 -8
- data/example/send_most_money.rb +1 -1
- data/example/square_tiling.rb +2 -2
- data/example/sudoku-set.rb +11 -12
- data/example/sudoku.rb +40 -45
- data/ext/extconf.rb +0 -0
- data/ext/gecode-2.1.1/LICENSE +0 -0
- data/ext/gecode-2.1.1/configure +0 -0
- data/ext/gecode-2.1.1/contribs/qecode/SDFVariableHeuristic.cc +0 -0
- data/ext/gecode-2.1.1/contribs/qecode/SDFVariableHeuristic.hh +0 -0
- data/ext/gecode-2.1.1/contribs/qecode/configure +0 -0
- data/ext/gecode-2.1.1/contribs/qecode/extensivecomparator.cc +0 -0
- data/ext/gecode-2.1.1/contribs/qecode/extensivecomparator.hh +0 -0
- data/ext/gecode-2.1.1/contribs/qecode/heap.cc +0 -0
- data/ext/gecode-2.1.1/contribs/qecode/implicative.cc +0 -0
- data/ext/gecode-2.1.1/contribs/qecode/implicative.hh +0 -0
- data/ext/gecode-2.1.1/contribs/qecode/myspace.cc +0 -0
- data/ext/gecode-2.1.1/contribs/qecode/myspace.hh +0 -0
- data/ext/gecode-2.1.1/contribs/qecode/qecore.cc +0 -0
- data/ext/gecode-2.1.1/contribs/qecode/qecore.hh +0 -0
- data/ext/gecode-2.1.1/contribs/qecode/warner.cc +0 -0
- data/ext/gecode-2.1.1/contribs/qecode/warner.hh +0 -0
- data/ext/gecode-2.1.1/gecode/cpltset/var-imp/cpltset.vis +0 -0
- data/ext/gecode-2.1.1/gecode/int/arithmetic/abs.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/arithmetic/max.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/arithmetic/mult.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/arithmetic/sqr.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/arithmetic/sqrt.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/array.cc +0 -0
- data/ext/gecode-2.1.1/gecode/int/array.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/bool/base.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/bool/eq.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/bool/eqv.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/bool/lq.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/bool/or.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/branch/select-val.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/branch/select-view.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/branch.cc +0 -0
- data/ext/gecode-2.1.1/gecode/int/branch.hh +0 -0
- data/ext/gecode-2.1.1/gecode/int/channel/base.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/channel/dom.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/channel/link-multi.cc +0 -0
- data/ext/gecode-2.1.1/gecode/int/channel/link-multi.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/channel/link-single.cc +0 -0
- data/ext/gecode-2.1.1/gecode/int/channel/link-single.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/channel/val.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/channel.cc +0 -0
- data/ext/gecode-2.1.1/gecode/int/channel.hh +0 -0
- data/ext/gecode-2.1.1/gecode/int/circuit/base.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/circuit/dom.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/circuit/val.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/circuit.cc +0 -0
- data/ext/gecode-2.1.1/gecode/int/circuit.hh +0 -0
- data/ext/gecode-2.1.1/gecode/int/count/int.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/count/rel.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/count/view.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/distinct/bilink.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/distinct/bnd.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/distinct/combptr.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/distinct/dom.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/distinct/edge.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/distinct/node.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/distinct/ter-dom.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/distinct/val.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/dom/range.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/dom/spec.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/dom.cc +0 -0
- data/ext/gecode-2.1.1/gecode/int/dom.hh +0 -0
- data/ext/gecode-2.1.1/gecode/int/element/int.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/element/view.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/element.cc +0 -0
- data/ext/gecode-2.1.1/gecode/int/element.hh +0 -0
- data/ext/gecode-2.1.1/gecode/int/exception.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/extensional/dfa.cc +0 -0
- data/ext/gecode-2.1.1/gecode/int/extensional/dfa.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/extensional/layered-graph.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/gcc/dom.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/gcc/gccbndsup.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/gcc/lbc.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/gcc/ubc.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/gcc.cc +0 -0
- data/ext/gecode-2.1.1/gecode/int/gcc.hh +0 -0
- data/ext/gecode-2.1.1/gecode/int/int-set.cc +0 -0
- data/ext/gecode-2.1.1/gecode/int/int-set.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/linear/bool-int.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/linear/bool-post.cc +0 -0
- data/ext/gecode-2.1.1/gecode/int/linear/bool-scale.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/linear/bool-view.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/linear/int-bin.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/linear/int-dom.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/linear/int-nary.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/linear/int-post.cc +0 -0
- data/ext/gecode-2.1.1/gecode/int/linear/int-ter.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/linear/post.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/propagator.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/rel/eq.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/rel/lex.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/rel/lq-le.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/rel/nq.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/unshare.cc +0 -0
- data/ext/gecode-2.1.1/gecode/int/var/bool.cc +0 -0
- data/ext/gecode-2.1.1/gecode/int/var-imp/bool.cc +0 -0
- data/ext/gecode-2.1.1/gecode/int/var-imp/bool.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/var-imp/bool.vis +0 -0
- data/ext/gecode-2.1.1/gecode/int/var-imp/delta.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/var-imp/int.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/var-imp/int.vis +0 -0
- data/ext/gecode-2.1.1/gecode/int/view/bool.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/view/constint.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/view/int.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/view/iter.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/view/minus.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/view/offset.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/view/print.cc +0 -0
- data/ext/gecode-2.1.1/gecode/int/view/rtest.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/view/scale.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/view/zero.icc +0 -0
- data/ext/gecode-2.1.1/gecode/int/view.icc +0 -0
- data/ext/gecode-2.1.1/gecode/iter/ranges-add.icc +0 -0
- data/ext/gecode-2.1.1/gecode/iter/ranges-append.icc +0 -0
- data/ext/gecode-2.1.1/gecode/iter/ranges-array.icc +0 -0
- data/ext/gecode-2.1.1/gecode/iter/ranges-cache.icc +0 -0
- data/ext/gecode-2.1.1/gecode/iter/ranges-compl.icc +0 -0
- data/ext/gecode-2.1.1/gecode/iter/ranges-diff.icc +0 -0
- data/ext/gecode-2.1.1/gecode/iter/ranges-empty.icc +0 -0
- data/ext/gecode-2.1.1/gecode/iter/ranges-inter.icc +0 -0
- data/ext/gecode-2.1.1/gecode/iter/ranges-minmax.icc +0 -0
- data/ext/gecode-2.1.1/gecode/iter/ranges-minus.icc +0 -0
- data/ext/gecode-2.1.1/gecode/iter/ranges-offset.icc +0 -0
- data/ext/gecode-2.1.1/gecode/iter/ranges-operations.icc +0 -0
- data/ext/gecode-2.1.1/gecode/iter/ranges-scale.icc +0 -0
- data/ext/gecode-2.1.1/gecode/iter/ranges-singleton-append.icc +0 -0
- data/ext/gecode-2.1.1/gecode/iter/ranges-singleton.icc +0 -0
- data/ext/gecode-2.1.1/gecode/iter/ranges-union.icc +0 -0
- data/ext/gecode-2.1.1/gecode/iter/ranges-values.icc +0 -0
- data/ext/gecode-2.1.1/gecode/iter/values-array.icc +0 -0
- data/ext/gecode-2.1.1/gecode/iter/values-minus.icc +0 -0
- data/ext/gecode-2.1.1/gecode/iter/values-offset.icc +0 -0
- data/ext/gecode-2.1.1/gecode/iter/values-ranges.icc +0 -0
- data/ext/gecode-2.1.1/gecode/iter/values-singleton.icc +0 -0
- data/ext/gecode-2.1.1/gecode/iter/values-unique.icc +0 -0
- data/ext/gecode-2.1.1/gecode/iter.hh +0 -0
- data/ext/gecode-2.1.1/gecode/kernel/advisor.icc +0 -0
- data/ext/gecode-2.1.1/gecode/kernel/array.icc +0 -0
- data/ext/gecode-2.1.1/gecode/kernel/branching.icc +0 -0
- data/ext/gecode-2.1.1/gecode/kernel/exception.icc +0 -0
- data/ext/gecode-2.1.1/gecode/kernel/macros.icc +0 -0
- data/ext/gecode-2.1.1/gecode/kernel/memory-manager.icc +0 -0
- data/ext/gecode-2.1.1/gecode/kernel/modevent.icc +0 -0
- data/ext/gecode-2.1.1/gecode/kernel/propagator.icc +0 -0
- data/ext/gecode-2.1.1/gecode/kernel/shared-array.icc +0 -0
- data/ext/gecode-2.1.1/gecode/kernel/var-traits.icc +0 -0
- data/ext/gecode-2.1.1/gecode/kernel/var.icc +0 -0
- data/ext/gecode-2.1.1/gecode/kernel/view.icc +0 -0
- data/ext/gecode-2.1.1/gecode/kernel.hh +0 -0
- data/ext/gecode-2.1.1/gecode/minimodel/arithmetic.cc +0 -0
- data/ext/gecode-2.1.1/gecode/minimodel/bool-expr.cc +0 -0
- data/ext/gecode-2.1.1/gecode/minimodel/bool-expr.icc +0 -0
- data/ext/gecode-2.1.1/gecode/minimodel/bool-rel.icc +0 -0
- data/ext/gecode-2.1.1/gecode/minimodel/lin-expr.icc +0 -0
- data/ext/gecode-2.1.1/gecode/minimodel/lin-rel.icc +0 -0
- data/ext/gecode-2.1.1/gecode/minimodel/reg.cc +0 -0
- data/ext/gecode-2.1.1/gecode/minimodel.hh +0 -0
- data/ext/gecode-2.1.1/gecode/search/bab.cc +0 -0
- data/ext/gecode-2.1.1/gecode/search/bab.icc +0 -0
- data/ext/gecode-2.1.1/gecode/search/dfs.cc +0 -0
- data/ext/gecode-2.1.1/gecode/search/dfs.icc +0 -0
- data/ext/gecode-2.1.1/gecode/search/engine-ctrl.icc +0 -0
- data/ext/gecode-2.1.1/gecode/search/lds.cc +0 -0
- data/ext/gecode-2.1.1/gecode/search/lds.icc +0 -0
- data/ext/gecode-2.1.1/gecode/search/options.cc +0 -0
- data/ext/gecode-2.1.1/gecode/search/options.icc +0 -0
- data/ext/gecode-2.1.1/gecode/search/reco-stack.icc +0 -0
- data/ext/gecode-2.1.1/gecode/search/restart.icc +0 -0
- data/ext/gecode-2.1.1/gecode/search/statistics.icc +0 -0
- data/ext/gecode-2.1.1/gecode/search/stop.cc +0 -0
- data/ext/gecode-2.1.1/gecode/search/stop.icc +0 -0
- data/ext/gecode-2.1.1/gecode/set/var-imp/set.vis +0 -0
- data/ext/gecode-2.1.1/gecode/support/block-allocator.icc +0 -0
- data/ext/gecode-2.1.1/gecode/support/cast.icc +0 -0
- data/ext/gecode-2.1.1/gecode/support/exception.cc +0 -0
- data/ext/gecode-2.1.1/gecode/support/exception.icc +0 -0
- data/ext/gecode-2.1.1/gecode/support/macros.icc +0 -0
- data/ext/gecode-2.1.1/gecode/support/marked-pointer.icc +0 -0
- data/ext/gecode-2.1.1/gecode/support/memory.icc +0 -0
- data/ext/gecode-2.1.1/gecode/support/sentinel-stack.icc +0 -0
- data/ext/gecode-2.1.1/gecode/support/static-stack.icc +0 -0
- data/ext/gecode-2.1.1/gecode/support/symbol.cc +0 -0
- data/ext/gecode-2.1.1/gecode/support.hh +0 -0
- data/ext/gecode-2.1.1/install-sh +0 -0
- data/ext/gecode-2.1.1/misc/debian/rules +0 -0
- data/ext/gecode-2.1.1/misc/doxygen/back.png +0 -0
- data/ext/gecode-2.1.1/misc/doxygen/gecode-logo-100.png +0 -0
- data/ext/gecode-2.1.1/misc/genchangelog.perl +0 -0
- data/ext/gecode-2.1.1/misc/genlicense.perl +0 -0
- data/ext/gecode-2.1.1/misc/genstatistics.perl +0 -0
- data/ext/gecode-2.1.1/misc/genvariables.perl +0 -0
- data/ext/gecode-2.1.1/misc/getrevision.perl +0 -0
- data/ext/gecode-2.1.1/misc/makedepend.perl +0 -0
- data/ext/gecode-2.1.1/misc/svn-ignore.txt +0 -0
- data/ext/gecode-2.1.1/variables.vsl +0 -0
- data/lib/gecoder/bindings/bindings.rb +16 -0
- data/lib/gecoder/bindings.rb +42 -0
- data/lib/gecoder/interface/branch.rb +16 -9
- data/lib/gecoder/interface/constraints/bool/boolean.rb +205 -213
- data/lib/gecoder/interface/constraints/bool/channel.rb +4 -5
- data/lib/gecoder/interface/constraints/bool/linear.rb +192 -21
- data/lib/gecoder/interface/constraints/bool_enum/channel.rb +43 -39
- data/lib/gecoder/interface/constraints/bool_enum/extensional.rb +43 -49
- data/lib/gecoder/interface/constraints/bool_enum/relation.rb +38 -71
- data/lib/gecoder/interface/constraints/bool_enum_constraints.rb +73 -22
- data/lib/gecoder/interface/constraints/bool_var_constraints.rb +140 -61
- data/lib/gecoder/interface/constraints/extensional_regexp.rb +4 -4
- data/lib/gecoder/interface/constraints/fixnum_enum/element.rb +63 -0
- data/lib/gecoder/interface/constraints/fixnum_enum/operation.rb +65 -0
- data/lib/gecoder/interface/constraints/fixnum_enum_constraints.rb +42 -0
- data/lib/gecoder/interface/constraints/int/arithmetic.rb +131 -130
- data/lib/gecoder/interface/constraints/int/channel.rb +21 -31
- data/lib/gecoder/interface/constraints/int/domain.rb +45 -42
- data/lib/gecoder/interface/constraints/int/linear.rb +85 -239
- data/lib/gecoder/interface/constraints/int/relation.rb +141 -0
- data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +55 -64
- data/lib/gecoder/interface/constraints/int_enum/channel.rb +35 -37
- data/lib/gecoder/interface/constraints/int_enum/count.rb +53 -78
- data/lib/gecoder/interface/constraints/int_enum/distinct.rb +36 -46
- data/lib/gecoder/interface/constraints/int_enum/element.rb +39 -57
- data/lib/gecoder/interface/constraints/int_enum/equality.rb +15 -19
- data/lib/gecoder/interface/constraints/int_enum/extensional.rb +65 -72
- data/lib/gecoder/interface/constraints/int_enum/sort.rb +42 -45
- data/lib/gecoder/interface/constraints/int_enum_constraints.rb +79 -22
- data/lib/gecoder/interface/constraints/int_var_constraints.rb +215 -44
- data/lib/gecoder/interface/constraints/reifiable_constraints.rb +14 -14
- data/lib/gecoder/interface/constraints/selected_set/select.rb +120 -0
- data/lib/gecoder/interface/constraints/selected_set_constraints.rb +75 -0
- data/lib/gecoder/interface/constraints/set/cardinality.rb +43 -53
- data/lib/gecoder/interface/constraints/set/channel.rb +26 -29
- data/lib/gecoder/interface/constraints/set/connection.rb +89 -152
- data/lib/gecoder/interface/constraints/set/domain.rb +112 -65
- data/lib/gecoder/interface/constraints/set/include.rb +36 -0
- data/lib/gecoder/interface/constraints/set/operation.rb +96 -110
- data/lib/gecoder/interface/constraints/set/relation.rb +114 -137
- data/lib/gecoder/interface/constraints/set_elements/relation.rb +116 -0
- data/lib/gecoder/interface/constraints/set_elements_constraints.rb +97 -0
- data/lib/gecoder/interface/constraints/set_enum/channel.rb +23 -27
- data/lib/gecoder/interface/constraints/set_enum/distinct.rb +18 -19
- data/lib/gecoder/interface/constraints/set_enum/operation.rb +62 -53
- data/lib/gecoder/interface/constraints/set_enum/select.rb +79 -0
- data/lib/gecoder/interface/constraints/set_enum_constraints.rb +73 -23
- data/lib/gecoder/interface/constraints/set_var_constraints.rb +222 -57
- data/lib/gecoder/interface/constraints.rb +410 -451
- data/lib/gecoder/interface/enum_matrix.rb +4 -4
- data/lib/gecoder/interface/enum_wrapper.rb +71 -22
- data/lib/gecoder/interface/model.rb +167 -12
- data/lib/gecoder/interface/model_sugar.rb +84 -0
- data/lib/gecoder/interface/search.rb +30 -18
- data/lib/gecoder/interface/variables.rb +103 -33
- data/lib/gecoder/interface.rb +2 -1
- data/lib/gecoder/version.rb +2 -2
- data/specs/bool_var.rb +19 -12
- data/specs/constraints/{boolean.rb → bool/boolean.rb} +103 -28
- data/specs/constraints/bool/boolean_properties.rb +51 -0
- data/specs/constraints/bool/linear.rb +213 -0
- data/specs/constraints/bool_enum/bool_enum_relation.rb +117 -0
- data/specs/constraints/bool_enum/channel.rb +102 -0
- data/specs/constraints/{extensional.rb → bool_enum/extensional.rb} +32 -101
- data/specs/constraints/constraint_helper.rb +149 -179
- data/specs/constraints/constraint_receivers.rb +103 -0
- data/specs/constraints/constraints.rb +6 -63
- data/specs/constraints/fixnum_enum/element.rb +58 -0
- data/specs/constraints/fixnum_enum/operation.rb +67 -0
- data/specs/constraints/int/arithmetic.rb +149 -0
- data/specs/constraints/int/channel.rb +101 -0
- data/specs/constraints/int/domain.rb +106 -0
- data/specs/constraints/int/linear.rb +183 -0
- data/specs/constraints/int/linear_properties.rb +97 -0
- data/specs/constraints/int/relation.rb +84 -0
- data/specs/constraints/int_enum/arithmetic.rb +72 -0
- data/specs/constraints/int_enum/channel.rb +57 -0
- data/specs/constraints/int_enum/count.rb +72 -0
- data/specs/constraints/int_enum/distinct.rb +80 -0
- data/specs/constraints/int_enum/element.rb +61 -0
- data/specs/constraints/int_enum/equality.rb +29 -0
- data/specs/constraints/int_enum/extensional.rb +224 -0
- data/specs/constraints/int_enum/sort.rb +167 -0
- data/specs/constraints/operands.rb +264 -0
- data/specs/constraints/property_helper.rb +443 -0
- data/specs/constraints/reification_sugar.rb +4 -5
- data/specs/constraints/selected_set/select.rb +56 -0
- data/specs/constraints/selected_set/select_properties.rb +157 -0
- data/specs/constraints/set/cardinality.rb +58 -0
- data/specs/constraints/set/cardinality_properties.rb +46 -0
- data/specs/constraints/set/channel.rb +77 -0
- data/specs/constraints/set/connection.rb +176 -0
- data/specs/constraints/set/domain.rb +197 -0
- data/specs/constraints/set/include.rb +36 -0
- data/specs/constraints/set/operation.rb +132 -0
- data/specs/constraints/set/relation.rb +117 -0
- data/specs/constraints/set_elements/relation.rb +84 -0
- data/specs/constraints/set_enum/channel.rb +80 -0
- data/specs/constraints/set_enum/distinct.rb +59 -0
- data/specs/constraints/set_enum/operation.rb +111 -0
- data/specs/constraints/set_enum/select.rb +73 -0
- data/specs/enum_wrapper.rb +53 -3
- data/specs/int_var.rb +44 -25
- data/specs/model.rb +58 -1
- data/specs/model_sugar.rb +30 -0
- data/specs/search.rb +24 -5
- data/specs/selected_set.rb +39 -0
- data/specs/set_elements.rb +34 -0
- data/specs/set_var.rb +22 -8
- data/specs/spec_helper.rb +206 -6
- data/tasks/distribution.rake +22 -7
- data/tasks/svn.rake +3 -1
- metadata +219 -135
- data/lib/gecoder/interface/constraints/set_enum/selection.rb +0 -217
- data/specs/constraints/arithmetic.rb +0 -351
- data/specs/constraints/bool_enum_relation.rb +0 -160
- data/specs/constraints/cardinality.rb +0 -157
- data/specs/constraints/channel.rb +0 -454
- data/specs/constraints/connection.rb +0 -369
- data/specs/constraints/count.rb +0 -146
- data/specs/constraints/distinct.rb +0 -164
- data/specs/constraints/element.rb +0 -108
- data/specs/constraints/equality.rb +0 -31
- data/specs/constraints/int_domain.rb +0 -70
- data/specs/constraints/int_relation.rb +0 -82
- data/specs/constraints/linear.rb +0 -340
- data/specs/constraints/selection.rb +0 -292
- data/specs/constraints/set_domain.rb +0 -185
- data/specs/constraints/set_operation.rb +0 -285
- data/specs/constraints/set_relation.rb +0 -197
- data/specs/constraints/sort.rb +0 -179
|
@@ -1,58 +1,229 @@
|
|
|
1
|
-
module
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
# A module that deals with the operands, properties and constraints of
|
|
2
|
+
# integer variables.
|
|
3
|
+
module Gecode::Int #:nodoc:
|
|
4
|
+
# A IntOperand is a combination of variables on which the
|
|
5
|
+
# constraints defined in IntConstraintReceiver can be placed.
|
|
6
|
+
#
|
|
7
|
+
# Integer operands can be created either by using
|
|
8
|
+
# Gecode::Model#int_var et al, or by using properties that produce
|
|
9
|
+
# integer operands. The operands, no matter how they were created,
|
|
10
|
+
# all respond to the properties defined by IntOperand.
|
|
11
|
+
#
|
|
12
|
+
# ==== Examples
|
|
13
|
+
#
|
|
14
|
+
# Produces a single integer operand (more specifically an IntVar) with
|
|
15
|
+
# domain 0..9 inside a problem formulation, using
|
|
16
|
+
# Gecode::Model#int_var:
|
|
17
|
+
#
|
|
18
|
+
# int_operand = int_var(0..9)
|
|
19
|
+
#
|
|
20
|
+
# Uses the IntOperand#+ property to produce a new integer
|
|
21
|
+
# operand representing +int_operand1+ plus +int_operand2+:
|
|
22
|
+
#
|
|
23
|
+
# new_int_operand = int_operand1 + int_operand2
|
|
24
|
+
#
|
|
25
|
+
# Uses the IntEnumOperand#max property to produce a new
|
|
26
|
+
# integer operand representing the maximum value of the integer operands
|
|
27
|
+
# in the enumeration +int_enum+:
|
|
28
|
+
#
|
|
29
|
+
# new_int_operand = int_enum.max
|
|
30
|
+
#
|
|
31
|
+
# Uses the IntEnumOperand#[] property to produce a new integer operand
|
|
32
|
+
# representing the integer operand at the index decided by
|
|
33
|
+
# +int_operand+ (which can change during search) in the enumeration
|
|
34
|
+
# +int_enum+:
|
|
35
|
+
#
|
|
36
|
+
# new_int_operand = int_enum[int_operand]
|
|
37
|
+
#
|
|
38
|
+
# Uses the SetOperand#size property to produce a new integer operand
|
|
39
|
+
# representing the size of +set_operand+:
|
|
40
|
+
#
|
|
41
|
+
# new_int_operand = set_operand.size
|
|
42
|
+
#
|
|
43
|
+
#--
|
|
44
|
+
# Classes that mix in IntOperand must define #model and #to_int_var .
|
|
45
|
+
module IntOperand
|
|
46
|
+
include Gecode::Operand
|
|
47
|
+
|
|
48
|
+
def method_missing(method, *args) #:nodoc:
|
|
49
|
+
if Gecode::IntVar.instance_methods.include? method.to_s
|
|
50
|
+
# Delegate to the int var.
|
|
51
|
+
to_int_var.method(method).call(*args)
|
|
52
|
+
else
|
|
53
|
+
super
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
5
57
|
private
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
58
|
+
|
|
59
|
+
def construct_receiver(params)
|
|
60
|
+
IntConstraintReceiver.new(model, params)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# An operand that short circuits integer equality.
|
|
65
|
+
class ShortCircuitEqualityOperand #:nodoc:
|
|
66
|
+
include Gecode::Int::IntOperand
|
|
67
|
+
attr :model
|
|
68
|
+
|
|
69
|
+
def initialize(model)
|
|
70
|
+
@model = model
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def construct_receiver(params)
|
|
9
74
|
params.update(:lhs => self)
|
|
10
|
-
|
|
75
|
+
receiver = IntConstraintReceiver.new(@model, params)
|
|
76
|
+
op = self
|
|
77
|
+
receiver.instance_eval{ @short_circuit = op }
|
|
78
|
+
class <<receiver
|
|
79
|
+
alias_method :equality_without_short_circuit, :==
|
|
80
|
+
def ==(operand, options = {})
|
|
81
|
+
if !@params[:negate] and options[:reify].nil? and
|
|
82
|
+
operand.respond_to? :to_int_var
|
|
83
|
+
# Short circuit the constraint.
|
|
84
|
+
@params.update Gecode::Util.decode_options(options)
|
|
85
|
+
@model.add_constraint(Gecode::BlockConstraint.new(
|
|
86
|
+
@model, @params) do
|
|
87
|
+
@short_circuit.constrain_equal(operand, false,
|
|
88
|
+
@params.values_at(:strength, :kind))
|
|
89
|
+
end)
|
|
90
|
+
else
|
|
91
|
+
equality_without_short_circuit(operand, options)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
alias_comparison_methods
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
return receiver
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def to_int_var
|
|
101
|
+
variable = model.int_var
|
|
102
|
+
options =
|
|
103
|
+
Gecode::Util.decode_options({}).values_at(:strength, :kind)
|
|
104
|
+
model.add_interaction do
|
|
105
|
+
constrain_equal(variable, true, options)
|
|
106
|
+
end
|
|
107
|
+
return variable
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
private
|
|
111
|
+
|
|
112
|
+
# Constrains this operand to equal +int_operand+ using the
|
|
113
|
+
# specified +propagation_options+. If +constrain_domain+ is true
|
|
114
|
+
# then the method should also attempt to constrain the bounds of the
|
|
115
|
+
# domain of +int_operand+.
|
|
116
|
+
def constrain_equal(int_operand, constrain_domain, propagation_options)
|
|
117
|
+
raise NotImplementedError, 'Abstract method has not been implemented.'
|
|
11
118
|
end
|
|
12
119
|
end
|
|
13
|
-
|
|
14
|
-
#
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
120
|
+
|
|
121
|
+
# An operand that short circuits integer relation constraints.
|
|
122
|
+
class ShortCircuitRelationsOperand #:nodoc:
|
|
123
|
+
include Gecode::Int::IntOperand
|
|
124
|
+
attr :model
|
|
125
|
+
|
|
126
|
+
def initialize(model)
|
|
127
|
+
@model = model
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def construct_receiver(params)
|
|
131
|
+
receiver = IntConstraintReceiver.new(@model, params)
|
|
132
|
+
op = self
|
|
133
|
+
receiver.instance_eval{ @short_circuit = op }
|
|
134
|
+
class <<receiver
|
|
135
|
+
Gecode::Util::COMPARISON_ALIASES.keys.each do |comp|
|
|
136
|
+
eval <<-end_code
|
|
137
|
+
alias_method :alias_#{comp.to_i}_without_short_circuit, :#{comp}
|
|
138
|
+
def #{comp}(operand, options = {})
|
|
139
|
+
if operand.respond_to?(:to_int_var) or operand.kind_of? Fixnum
|
|
140
|
+
# Short circuit the constraint.
|
|
141
|
+
@params.update Gecode::Util.decode_options(options)
|
|
142
|
+
@model.add_constraint(
|
|
143
|
+
@short_circuit.relation_constraint(
|
|
144
|
+
:#{comp}, operand, @params))
|
|
145
|
+
else
|
|
146
|
+
alias_#{comp.to_i}_without_short_circuit(operand, options)
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end_code
|
|
150
|
+
end
|
|
151
|
+
alias_comparison_methods
|
|
31
152
|
end
|
|
153
|
+
|
|
154
|
+
return receiver
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def to_int_var
|
|
158
|
+
variable = model.int_var
|
|
159
|
+
params = {}
|
|
160
|
+
params.update Gecode::Util.decode_options({})
|
|
161
|
+
model.add_constraint relation_constraint(:==, variable, params)
|
|
162
|
+
return variable
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Returns a constraint that constrains this operand to have relation
|
|
166
|
+
# +relation+ to +int_operand_or_fix+, which is either an integer
|
|
167
|
+
# operand or a fixnum, given the specified hash +params+ of parameters.
|
|
168
|
+
def relation_constraint(relation, int_operand_or_fix, params)
|
|
169
|
+
raise NotImplementedError, 'Abstract method has not been implemented.'
|
|
32
170
|
end
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# IntConstraintReceiver contains all constraints that can be
|
|
174
|
+
# placed on an IntOperand.
|
|
175
|
+
#
|
|
176
|
+
# Constraints are placed by calling IntOperand#must (or any other
|
|
177
|
+
# of the variations defined in Operand), which produces a
|
|
178
|
+
# IntConstraintReceiver from which the desired constraint can be used.
|
|
179
|
+
#
|
|
180
|
+
# Each constraint accepts a number of options. See ConstraintReceiver
|
|
181
|
+
# for more information.
|
|
182
|
+
#
|
|
183
|
+
# ==== Examples
|
|
184
|
+
#
|
|
185
|
+
# Constrains +int_operand+ to be strictly greater than 5 using
|
|
186
|
+
# IntConstraintReceiver#>:
|
|
187
|
+
#
|
|
188
|
+
# int_operand.must > 5
|
|
189
|
+
#
|
|
190
|
+
# Constrains +int_operand1+ plus +int_operand2+ to be strictly
|
|
191
|
+
# greater than 5 using the IntOperand#+ property and
|
|
192
|
+
# IntConstraintReceiver#>:
|
|
193
|
+
#
|
|
194
|
+
# (int_operand1 + int_operand2).must > 5
|
|
195
|
+
#
|
|
196
|
+
# Constrains the maximum value of the integer operands in +int_enum+ to
|
|
197
|
+
# _not_ be in the range 3..7 using the IntEnumOperand#max property and
|
|
198
|
+
# IntConstraintReceiver#in:
|
|
199
|
+
#
|
|
200
|
+
# int_enum.max.must_not_be.in 3..7
|
|
201
|
+
#
|
|
202
|
+
# Constrains the integer operand at position +int_operand+ in
|
|
203
|
+
# +int_enum+, an enumeration of integer operands, to be greater than
|
|
204
|
+
# or equal to +int_operand2+. This uses the IntEnumOperand#[] property
|
|
205
|
+
# and IntConstraintReceiver#>=:
|
|
206
|
+
#
|
|
207
|
+
# int_enum[int_operand].must >= int_operand2
|
|
208
|
+
#
|
|
209
|
+
# The same as above, but specifying that strength :domain should be
|
|
210
|
+
# used and that the constraint should be reified with +bool_operand+:
|
|
211
|
+
#
|
|
212
|
+
# int_enum[int_operand].must_be.greater_or_equal(int_operand2, :strength => :domain, :reify => bool_operand)
|
|
213
|
+
#
|
|
214
|
+
class IntConstraintReceiver < Gecode::ConstraintReceiver
|
|
215
|
+
# Raises TypeError unless the left hand side is an int operand.
|
|
216
|
+
def initialize(model, params) #:nodoc:
|
|
217
|
+
super
|
|
218
|
+
|
|
219
|
+
unless params[:lhs].respond_to? :to_int_var
|
|
220
|
+
raise TypeError, 'Must have int operand as left hand side.'
|
|
51
221
|
end
|
|
52
222
|
end
|
|
53
223
|
end
|
|
54
224
|
end
|
|
55
225
|
|
|
226
|
+
require 'gecoder/interface/constraints/int/relation'
|
|
56
227
|
require 'gecoder/interface/constraints/int/linear'
|
|
57
228
|
require 'gecoder/interface/constraints/int/domain'
|
|
58
229
|
require 'gecoder/interface/constraints/int/arithmetic'
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
module Gecode
|
|
1
|
+
module Gecode
|
|
2
2
|
# Base class for all reifiable constraints.
|
|
3
|
-
class ReifiableConstraint < Constraint
|
|
4
|
-
# Gets the reification
|
|
3
|
+
class ReifiableConstraint < Constraint #:nodoc:
|
|
4
|
+
# Gets the reification operand of the constraint, nil if none exists.
|
|
5
5
|
def reification_var
|
|
6
6
|
@params[:reif]
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
-
# Sets the reification
|
|
9
|
+
# Sets the reification operand of the constraint, nil if none should be
|
|
10
10
|
# used.
|
|
11
11
|
def reification_var=(new_var)
|
|
12
12
|
@params[:reif] = new_var
|
|
@@ -15,7 +15,7 @@ module Gecode::Constraints
|
|
|
15
15
|
# Produces a disjunction of two reifiable constraints, producing a new
|
|
16
16
|
# reifiable constraint.
|
|
17
17
|
def |(constraint)
|
|
18
|
-
|
|
18
|
+
with_reification_operands(constraint) do |b1, b2|
|
|
19
19
|
# Create the disjunction constraint.
|
|
20
20
|
(b1 | b2).must_be.true
|
|
21
21
|
end
|
|
@@ -24,7 +24,7 @@ module Gecode::Constraints
|
|
|
24
24
|
# Produces a conjunction of two reifiable constraints, producing a new
|
|
25
25
|
# reifiable constraint.
|
|
26
26
|
def &(constraint)
|
|
27
|
-
|
|
27
|
+
with_reification_operands(constraint) do |b1, b2|
|
|
28
28
|
# Create the conjunction constraint.
|
|
29
29
|
(b1 & b2).must_be.true
|
|
30
30
|
end
|
|
@@ -32,14 +32,14 @@ module Gecode::Constraints
|
|
|
32
32
|
|
|
33
33
|
private
|
|
34
34
|
|
|
35
|
-
# Yields two boolean
|
|
36
|
-
# self's reification
|
|
37
|
-
# of the specified constraint. Reuses
|
|
38
|
-
# otherwise creates new ones.
|
|
39
|
-
def
|
|
35
|
+
# Yields two boolean operands to the specified block. The first one
|
|
36
|
+
# is self's reification operand and the second one is the
|
|
37
|
+
# reification operand of the specified constraint. Reuses
|
|
38
|
+
# reification operands if possible, otherwise creates new ones.
|
|
39
|
+
def with_reification_operands(constraint, &block)
|
|
40
40
|
raise TypeError unless constraint.kind_of? ReifiableConstraint
|
|
41
41
|
|
|
42
|
-
# Set up the reification
|
|
42
|
+
# Set up the reification operands, using existing operands if they
|
|
43
43
|
# exist.
|
|
44
44
|
con1_holds = self.reification_var
|
|
45
45
|
con2_holds = constraint.reification_var
|
|
@@ -55,7 +55,7 @@ module Gecode::Constraints
|
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
# If called the negation of the constraint will be handled using the
|
|
58
|
-
# reification
|
|
58
|
+
# reification operand. This means that the post method (which has to be
|
|
59
59
|
# defined prior to calling this method) doesn't have to bother about
|
|
60
60
|
# negation.
|
|
61
61
|
def self.negate_using_reification
|
|
@@ -75,4 +75,4 @@ module Gecode::Constraints
|
|
|
75
75
|
end
|
|
76
76
|
end
|
|
77
77
|
end
|
|
78
|
-
end
|
|
78
|
+
end
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
module Gecode::SelectedSet
|
|
2
|
+
class SelectedSetOperand
|
|
3
|
+
# Produces a SetOperand representing the selected sets' union.
|
|
4
|
+
#
|
|
5
|
+
# ==== Examples
|
|
6
|
+
#
|
|
7
|
+
# # The union of all sets selected by +set_enum[set]+.
|
|
8
|
+
# set_enum[set].union
|
|
9
|
+
def union
|
|
10
|
+
Select::SelectedSetUnionOperand.new(model, self)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Produces a SetOperand representing the selected sets' intersection.
|
|
14
|
+
# The option :with can be used to enumerate the elements in the
|
|
15
|
+
# universe.
|
|
16
|
+
#
|
|
17
|
+
# ==== Examples
|
|
18
|
+
#
|
|
19
|
+
# # The intersection of all sets selected by +set_enum[set]+.
|
|
20
|
+
# set_enum[set].intersection
|
|
21
|
+
#
|
|
22
|
+
# # The same intersection as above, but with [3,5,7] as universe.
|
|
23
|
+
# set_enum[set].intersection(:with => [3,5,7])
|
|
24
|
+
def intersection(options = {})
|
|
25
|
+
universe = nil
|
|
26
|
+
unless options.empty?
|
|
27
|
+
unless options.size == 1 and options.has_key?(:with)
|
|
28
|
+
raise ArgumentError, "Expected option key :with, got #{options.keys}."
|
|
29
|
+
else
|
|
30
|
+
universe = options[:with]
|
|
31
|
+
unless universe.kind_of?(Enumerable) and
|
|
32
|
+
universe.all?{ |element| element.kind_of? Fixnum }
|
|
33
|
+
raise TypeError, "Expected the universe to be specified as " +
|
|
34
|
+
"an enumeration of fixnum, got #{universe.class}."
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
Select::SelectedSetIntersectionOperand.new(model, self, universe)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
class SelectedSetConstraintReceiver
|
|
44
|
+
# Constrains the selected sets to be pairwise disjoint.
|
|
45
|
+
#
|
|
46
|
+
# ==== Examples
|
|
47
|
+
#
|
|
48
|
+
# # Constrains all sets selected by +set_enum[set]+ to be pairwise
|
|
49
|
+
# # disjoint.
|
|
50
|
+
# set_enum[set].must_be.disjoint
|
|
51
|
+
def disjoint(options = {})
|
|
52
|
+
if @params[:negate]
|
|
53
|
+
raise Gecode::MissingConstraintError, 'A negated disjoint constraint ' +
|
|
54
|
+
'is not implemented.'
|
|
55
|
+
end
|
|
56
|
+
if options.has_key? :reify
|
|
57
|
+
raise ArgumentError, 'The disjoint constraint does not support the ' +
|
|
58
|
+
'reification option.'
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
@params.update Gecode::Set::Util.decode_options(options)
|
|
62
|
+
@model.add_constraint Select::DisjointConstraint.new(@model, @params)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
module Select #:nodoc:
|
|
67
|
+
class SelectedSetUnionOperand < Gecode::Set::ShortCircuitEqualityOperand #:nodoc:
|
|
68
|
+
def initialize(model, selected_set)
|
|
69
|
+
super model
|
|
70
|
+
@selected_set = selected_set
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def constrain_equal(set_operand, constrain, propagation_options)
|
|
74
|
+
enum, indices = @selected_set.to_selected_set
|
|
75
|
+
if constrain
|
|
76
|
+
set_operand.must_be.subset_of enum.upper_bound_range
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
Gecode::Raw::selectUnion(@model.active_space,
|
|
80
|
+
enum.to_set_enum.bind_array, indices.to_set_var.bind,
|
|
81
|
+
set_operand.to_set_var.bind)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
class SelectedSetIntersectionOperand < Gecode::Set::ShortCircuitEqualityOperand #:nodoc:
|
|
86
|
+
def initialize(model, selected_set, universe)
|
|
87
|
+
super model
|
|
88
|
+
@selected_set = selected_set
|
|
89
|
+
@universe = universe
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def constrain_equal(set_operand, constrain, propagation_options)
|
|
93
|
+
enum, indices = @selected_set.to_selected_set
|
|
94
|
+
universe = @universe
|
|
95
|
+
|
|
96
|
+
# We can't do any useful constraining here since the empty intersection
|
|
97
|
+
# is the universe.
|
|
98
|
+
|
|
99
|
+
if universe.nil?
|
|
100
|
+
Gecode::Raw::selectInter(@model.active_space,
|
|
101
|
+
enum.to_set_enum.bind_array, indices.to_set_var.bind,
|
|
102
|
+
set_operand.to_set_var.bind)
|
|
103
|
+
else
|
|
104
|
+
Gecode::Raw::selectInterIn(@model.active_space,
|
|
105
|
+
enum.to_set_enum.bind_array, indices.to_set_var.bind,
|
|
106
|
+
set_operand.to_set_var.bind,
|
|
107
|
+
Gecode::Util.constant_set_to_int_set(universe))
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
class DisjointConstraint < Gecode::Constraint #:nodoc:
|
|
113
|
+
def post
|
|
114
|
+
enum, indices = @params[:lhs].to_selected_set
|
|
115
|
+
Gecode::Raw.selectDisjoint(@model.active_space,
|
|
116
|
+
enum.to_set_enum.bind_array, indices.to_set_var.bind)
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# A module containing constraints that have set_enum[set] as left hand
|
|
2
|
+
# side.
|
|
3
|
+
module Gecode::SelectedSet #:nodoc:
|
|
4
|
+
# A SelectedSetOperand is an uncommon operand that results from calling
|
|
5
|
+
# SetEnumOperand#[] with a SetOperand. It facilitates placing the
|
|
6
|
+
# constraints defined in SelectedSetConstraintReceiver
|
|
7
|
+
#
|
|
8
|
+
# ==== Examples
|
|
9
|
+
#
|
|
10
|
+
# Producing a SelectedSetOperand from +set_enum+ and +set_operand+:
|
|
11
|
+
#
|
|
12
|
+
# set_enum[set_operand]
|
|
13
|
+
#
|
|
14
|
+
class SelectedSetOperand
|
|
15
|
+
include Gecode::Operand
|
|
16
|
+
|
|
17
|
+
# Constructs a new selected set operand from +set_enum+ and +set+.
|
|
18
|
+
def initialize(set_enum, set) #:nodoc:
|
|
19
|
+
unless set_enum.respond_to? :to_set_enum
|
|
20
|
+
raise TypeError, "Expected set enum operand, got #{set_enum.class}."
|
|
21
|
+
end
|
|
22
|
+
unless set.respond_to? :to_set_var
|
|
23
|
+
raise TypeError, "Expected set operand, got #{set.class}."
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
@set_enum = set_enum
|
|
27
|
+
@set = set
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Returns the set enum and set that make up the selected set
|
|
31
|
+
# operand.
|
|
32
|
+
def to_selected_set #:nodoc:
|
|
33
|
+
return @set_enum, @set
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def model #:nodoc:
|
|
37
|
+
@set_enum.model
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def construct_receiver(params)
|
|
43
|
+
SelectedSetConstraintReceiver.new(model, params)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# SelectedSetConstraintReceiver contains all constraints that can be
|
|
48
|
+
# placed on a SelectedSetOperand.
|
|
49
|
+
#
|
|
50
|
+
# Constraints are placed by calling SelectedSetOperand#must (or any other
|
|
51
|
+
# of the variations defined in Operand), which produces a
|
|
52
|
+
# SelectedSetConstraintReceiver from which the desired constraint can
|
|
53
|
+
# be used.
|
|
54
|
+
#
|
|
55
|
+
# ==== Examples
|
|
56
|
+
#
|
|
57
|
+
# Constrains the sets in +set_enum+ that are selected by +set_operand+ to be
|
|
58
|
+
# disjoint. This uses SetEnumOperand#[] and
|
|
59
|
+
# SelectedSetConstraintReceiver#disjoint.
|
|
60
|
+
#
|
|
61
|
+
# set_enum[set_operand].must_be.disjoint
|
|
62
|
+
#
|
|
63
|
+
class SelectedSetConstraintReceiver < Gecode::ConstraintReceiver
|
|
64
|
+
# Raises TypeError unless the left hand side is a selected set operand.
|
|
65
|
+
def initialize(model, params) #:nodoc:
|
|
66
|
+
super
|
|
67
|
+
|
|
68
|
+
unless params[:lhs].respond_to? :to_selected_set
|
|
69
|
+
raise TypeError, 'Must have selected set operand as left hand side.'
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
require 'gecoder/interface/constraints/selected_set/select'
|
|
@@ -1,75 +1,65 @@
|
|
|
1
|
-
module Gecode
|
|
2
|
-
|
|
3
|
-
#
|
|
1
|
+
module Gecode::Set
|
|
2
|
+
module SetOperand
|
|
3
|
+
# Produces an IntOperand representing the size of the set.
|
|
4
|
+
#
|
|
5
|
+
# ==== Examples
|
|
6
|
+
#
|
|
7
|
+
# # The size of +set+.
|
|
8
|
+
# set.size
|
|
4
9
|
def size
|
|
5
|
-
|
|
6
|
-
Gecode::Constraints::Set::Cardinality::SizeExpressionStub.new(
|
|
7
|
-
@model, params)
|
|
10
|
+
Cardinality::SetSizeOperand.new(@model, self)
|
|
8
11
|
end
|
|
9
12
|
end
|
|
10
|
-
end
|
|
11
13
|
|
|
12
|
-
module Gecode::Constraints::Set
|
|
13
14
|
# A module that gathers the classes and modules used in cardinality
|
|
14
15
|
# constraints.
|
|
15
16
|
module Cardinality #:nodoc:
|
|
16
17
|
# Describes a cardinality constraint specifically for ranges. This is just
|
|
17
18
|
# a special case which is used instead of the more general composite
|
|
18
19
|
# constraint when the target cardinality is a range.
|
|
19
|
-
class CardinalityConstraint < Gecode::
|
|
20
|
+
class CardinalityConstraint < Gecode::Constraint #:nodoc:
|
|
20
21
|
def post
|
|
21
22
|
var, range = @params.values_at(:lhs, :range)
|
|
22
|
-
Gecode::Raw::cardinality(@model.active_space, var.bind,
|
|
23
|
-
range.last)
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
# A custom composite stub to change the composite expression used.
|
|
28
|
-
class CompositeStub < Gecode::Constraints::CompositeStub #:nodoc:
|
|
29
|
-
def initialize(model, params)
|
|
30
|
-
super(Expression, model, params)
|
|
23
|
+
Gecode::Raw::cardinality(@model.active_space, var.to_set_var.bind,
|
|
24
|
+
range.first, range.last)
|
|
31
25
|
end
|
|
32
26
|
end
|
|
33
27
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
@params.update(:range => range)
|
|
39
|
-
@model.add_constraint CardinalityConstraint.new(@model, @params)
|
|
40
|
-
else
|
|
41
|
-
super(range)
|
|
42
|
-
end
|
|
28
|
+
class SetSizeOperand < Gecode::Int::ShortCircuitEqualityOperand #:nodoc:
|
|
29
|
+
def initialize(model, set_op)
|
|
30
|
+
super model
|
|
31
|
+
@set = set_op
|
|
43
32
|
end
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
# the cardianlity (size) of a set.
|
|
48
|
-
#
|
|
49
|
-
# == Example
|
|
50
|
-
#
|
|
51
|
-
# # The size of +set+ must be within 1..17
|
|
52
|
-
# set.size.must_be.in 1..17
|
|
53
|
-
#
|
|
54
|
-
# # The size must equal the integer variable +size+.
|
|
55
|
-
# set.size.must == size
|
|
56
|
-
#
|
|
57
|
-
# # The size must not be larger than 17
|
|
58
|
-
# set.size.must_not > 17
|
|
59
|
-
#
|
|
60
|
-
# # We reify the above with a boolean variable called +is_not_large+ and
|
|
61
|
-
# # select the strength +domain+.
|
|
62
|
-
# set.size.must_not_be.larger_than(17, :reify => is_not_large,
|
|
63
|
-
# :strength => :domain)
|
|
64
|
-
class SizeExpressionStub < CompositeStub
|
|
65
|
-
def constrain_equal(variable, params, constrain)
|
|
66
|
-
lhs = @params[:lhs]
|
|
33
|
+
|
|
34
|
+
def constrain_equal(int_operand, constrain, propagation_options)
|
|
35
|
+
set = @set.to_set_var
|
|
67
36
|
if constrain
|
|
68
|
-
|
|
37
|
+
int_operand.must_be.in set.lower_bound.size..set.upper_bound.size
|
|
69
38
|
end
|
|
70
39
|
|
|
71
|
-
Gecode::Raw::cardinality(@model.active_space,
|
|
40
|
+
Gecode::Raw::cardinality(@model.active_space, set.bind,
|
|
41
|
+
int_operand.to_int_var.bind)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
alias_method :pre_cardinality_construct_receiver, :construct_receiver
|
|
45
|
+
def construct_receiver(params)
|
|
46
|
+
receiver = pre_cardinality_construct_receiver(params)
|
|
47
|
+
set = @set
|
|
48
|
+
receiver.instance_eval{ @set = set }
|
|
49
|
+
class <<receiver
|
|
50
|
+
alias_method :in_without_short_circuit, :in
|
|
51
|
+
def in(range, options = {})
|
|
52
|
+
if range.kind_of?(Range) and !@params[:negate] and
|
|
53
|
+
!options.has_key?(:reify)
|
|
54
|
+
@params.update(:lhs => @set, :range => range)
|
|
55
|
+
@model.add_constraint CardinalityConstraint.new(@model, @params)
|
|
56
|
+
else
|
|
57
|
+
in_without_short_circuit(range, options)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
return receiver
|
|
72
62
|
end
|
|
73
63
|
end
|
|
74
64
|
end
|
|
75
|
-
end
|
|
65
|
+
end
|