Class: DepSelector::GecodeWrapper

Inherits:
Object
  • Object
show all
Defined in:
lib/dep_selector/gecode_wrapper.rb

Constant Summary collapse

DontCareConstraint =
-1
NoMatchConstraint =
-2
SolutionStateUnstarted =

from dep_selector_to_gecode_interface.h

1
SolutionStateFinalized =
2
SolutionStateSolved =
3
SolutionStateTimedOut =
4
SolutionStateOptimal =
5

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(problem_or_package_count, logId, debug = false, timeout = 10000) ⇒ GecodeWrapper

This insures that we properly deallocate the c++ class at the heart of dep_gecode. modeled after www.mikeperham.com/2010/02/24/the-trouble-with-ruby-finalizers/



54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/dep_selector/gecode_wrapper.rb', line 54

def initialize(problem_or_package_count, logId, debug=false, timeout = 10000)
  if (problem_or_package_count.is_a?(Numeric))
    dump_statistics = DepSelector.dump_statistics || debug
    @log_id = logId
    @debug_logs_on = debug
    @timeout = timeout
    @gecode_problem = Dep_gecode.VersionProblemCreate(problem_or_package_count, dump_statistics, debug, logId, @timeout)
  else
    @gecode_problem = problem_or_package_count
  end
  ObjectSpace.define_finalizer(self, self.class.finalize(@gecode_problem))
end

Instance Attribute Details

#debug_logs_onObject (readonly)

Returns the value of attribute debug_logs_on.



39
40
41
# File 'lib/dep_selector/gecode_wrapper.rb', line 39

def debug_logs_on
  @debug_logs_on
end

#gecode_problemObject (readonly)

Returns the value of attribute gecode_problem.



38
39
40
# File 'lib/dep_selector/gecode_wrapper.rb', line 38

def gecode_problem
  @gecode_problem
end

#log_idObject (readonly)

Returns the value of attribute log_id.



40
41
42
# File 'lib/dep_selector/gecode_wrapper.rb', line 40

def log_id
  @log_id
end

Class Method Details

.finalize(gecode_problem) ⇒ Object



66
67
68
# File 'lib/dep_selector/gecode_wrapper.rb', line 66

def self.finalize(gecode_problem)
  proc { Dep_gecode.VersionProblemDestroy(gecode_problem) }
end

Instance Method Details

#add_package(min, max, current_version) ⇒ Object



82
83
84
85
# File 'lib/dep_selector/gecode_wrapper.rb', line 82

def add_package(min, max, current_version)
  raise "Gecode internal failure" if gecode_problem.nil?
  Dep_gecode.AddPackage(gecode_problem, min, max, current_version)
end

#add_version_constraint(package_id, version, dependent_package_id, min_dependent_version, max_dependent_version) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/dep_selector/gecode_wrapper.rb', line 87

def add_version_constraint(package_id, version, dependent_package_id, min_dependent_version, max_dependent_version)
  raise "Gecode internal failure" if gecode_problem.nil?
  check_package_id(package_id, "package_id")
  check_package_id(dependent_package_id, "dependent_package_id")

  # Valid package versions are between -1 and its max (-1 means
  # don't care, meaning it doesn't need to be assigned). To
  # indicate constraints that match no versions, -2 is used, since
  # it's not a valid assignment of the variable; thus, any branch
  # that assigns -2 will fail.
  #
  # This mechanism is also used when a dependent package has no
  # versions, which only happens if the dependency's package is
  # auto-vivified when creating the parent PackageVersion's
  # dependency but with no corresponding set of PackageVersions
  # (i.e. it's an invalid deendency, because it does not exist in
  # the dependency graph). Again, we won't abort immediately, but
  # we'll add a constraint to the package that makes exploring
  # that portion of the solution space unsatisfiable. Thus it is
  # impossible to find solutions dependent on non-existent
  # packages.

  min = min_dependent_version || NoMatchConstraint
  max = max_dependent_version || NoMatchConstraint
  Dep_gecode.AddVersionConstraint(gecode_problem, package_id, version, dependent_package_id, min, max)

  # if the package was constrained to no versions, hint to the
  # solver that in the event of failure, it should prefer to
  # indicate constraints on dependent_package_id as the culprit
  if min == NoMatchConstraint && max == NoMatchConstraint
    Dep_gecode.MarkPackageSuspicious(gecode_problem, dependent_package_id)
  end
end

#check_package_id(package_id, param_name) ⇒ Object



70
71
72
# File 'lib/dep_selector/gecode_wrapper.rb', line 70

def check_package_id(package_id, param_name)
  raise "Gecode #{param_name} is out of range #{package_id}" unless (package_id >= 0 && package_id < self.size())
end

#dumpObject



141
142
143
144
# File 'lib/dep_selector/gecode_wrapper.rb', line 141

def dump()
  raise "Gecode internal failure" if gecode_problem.nil?
  Dep_gecode.VersionProblemDump(gecode_problem)
end

#dump_package_var(package_id) ⇒ Object



145
146
147
148
149
# File 'lib/dep_selector/gecode_wrapper.rb', line 145

def dump_package_var(package_id)
  raise "Gecode internal failure" if gecode_problem.nil?
  check_package_id(package_id, "package_id")
  Dep_gecode.VersionProblemPrintPackageVar(gecode_problem, package_id)
end

#get_package_max(package_id) ⇒ Object



131
132
133
134
135
# File 'lib/dep_selector/gecode_wrapper.rb', line 131

def get_package_max(package_id)
  raise "Gecode internal failure" if gecode_problem.nil?
  check_package_id(package_id, "package_id")
  Dep_gecode.GetPackageMax(gecode_problem, package_id)
end

#get_package_min(package_id) ⇒ Object



136
137
138
139
140
# File 'lib/dep_selector/gecode_wrapper.rb', line 136

def get_package_min(package_id)
  raise "Gecode internal failure" if gecode_problem.nil?
  check_package_id(package_id, "package_id")
  Dep_gecode.GetPackageMin(gecode_problem, package_id)
end

#get_package_version(package_id) ⇒ Object



120
121
122
123
124
# File 'lib/dep_selector/gecode_wrapper.rb', line 120

def get_package_version(package_id)
  raise "Gecode internal failure" if gecode_problem.nil?
  check_package_id(package_id, "package_id")
  Dep_gecode.GetPackageVersion(gecode_problem, package_id)
end

#get_solution_stateObject



173
174
175
176
# File 'lib/dep_selector/gecode_wrapper.rb', line 173

def get_solution_state()
  raise "Gecode internal failure (get_solution_state)" if gecode_problem.nil?
  Dep_gecode.GetSolutionState(gecode_problem);
end

#is_package_disabled?(package_id) ⇒ Boolean

Returns:

  • (Boolean)


125
126
127
128
129
# File 'lib/dep_selector/gecode_wrapper.rb', line 125

def is_package_disabled?(package_id)
  raise "Gecode internal failure" if gecode_problem.nil?
  check_package_id(package_id, "package_id")
  Dep_gecode.GetPackageDisabledState(gecode_problem, package_id);
end

#mark_preferred_to_be_at_latest(package_id, weight) ⇒ Object



162
163
164
165
166
# File 'lib/dep_selector/gecode_wrapper.rb', line 162

def mark_preferred_to_be_at_latest(package_id, weight)
  raise "Gecode internal failure (mark_preferred_to_be_at_latest)" if gecode_problem.nil?
  check_package_id(package_id, "package_id")
  Dep_gecode.MarkPackagePreferredToBeAtLatest(gecode_problem, package_id, weight);
end

#mark_required(package_id) ⇒ Object



156
157
158
159
160
# File 'lib/dep_selector/gecode_wrapper.rb', line 156

def mark_required(package_id)
  raise "Gecode internal failure (mark_required)" if gecode_problem.nil?
  check_package_id(package_id, "package_id")
  Dep_gecode.MarkPackageRequired(gecode_problem, package_id);
end

#package_countObject



78
79
80
81
# File 'lib/dep_selector/gecode_wrapper.rb', line 78

def package_count()
  raise "Gecode internal failure" if gecode_problem.nil?
  Dep_gecode.VersionProblemPackageCount(gecode_problem)
end

#package_disabled_countObject



151
152
153
154
# File 'lib/dep_selector/gecode_wrapper.rb', line 151

def package_disabled_count
  raise "Gecode internal failure (package disabled count)" if gecode_problem.nil?
  Dep_gecode.GetDisabledVariableCount(gecode_problem)
end

#set_timeout(timeout) ⇒ Object



168
169
170
171
# File 'lib/dep_selector/gecode_wrapper.rb', line 168

def set_timeout(timeout)
  raise "Gecode internal failure (set_timeout)" if gecode_problem.nil?
  Dep_gecode.SetTimeout(gecode_problem, timeout)
end

#sizeObject



74
75
76
77
# File 'lib/dep_selector/gecode_wrapper.rb', line 74

def size()
  raise "Gecode internal failure" if gecode_problem.nil?
  Dep_gecode.VersionProblemSize(gecode_problem)
end

#solveObject



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/dep_selector/gecode_wrapper.rb', line 178

def solve()
  raise "Gecode internal failure (solve)" if gecode_problem.nil?

  solutionPtr = FFI::MemoryPointer.new :pointer
  resultCode = Dep_gecode.Solve(gecode_problem, solutionPtr)
  solutionRaw = solutionPtr.get_pointer(0)

  solution = GecodeWrapper.new(solutionRaw, log_id, debug_logs_on, @timeout)

  raise "Gecode internal failure (no solution found)" if (solution.nil?)

  raise Exceptions::TimeBoundExceeded.new() if resultCode == SolutionStateTimedOut
  raise Exceptions::NoSolutionFound.new(solution) if solution.package_disabled_count > 0
  solution
end