Class: Ibex::DeltaReducer

Inherits:
Object
  • Object
show all
Defined in:
lib/ibex/delta_reducer.rb

Overview

Deterministic, trial-bounded delta debugging over an ordered sequence.

Defined Under Namespace

Classes: Result

Instance Method Summary collapse

Constructor Details

#initialize(max_trials: 1_000) ⇒ DeltaReducer

Returns a new instance of DeltaReducer.

Raises:

  • (ArgumentError)


25
26
27
28
29
# File 'lib/ibex/delta_reducer.rb', line 25

def initialize(max_trials: 1_000)
  raise ArgumentError, "max_trials must be positive" unless max_trials.positive?

  @max_trials = max_trials
end

Instance Method Details

#minimize(items, &failure) ⇒ Object

failure must return true while the failure of interest is preserved.

Raises:

  • (ArgumentError)


33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/ibex/delta_reducer.rb', line 33

def minimize(items, &failure)
  raise ArgumentError, "a failure predicate is required" unless failure

  current = items.dup
  original_size = current.length
  trials = 0
  trials = checked_trial!(trials)
  unless failure.call(current.freeze)
    raise Ibex::Error, "(reduce):1:1: original input does not reproduce the failure"
  end

  granularity = 2
  while current.length >= 1
    chunks = partitions(current.length, granularity)
    reduced = false
    chunks.each do |range|
      return result(current, trials, false, original_size) if trials >= @max_trials

      candidate = current.dup
      candidate.slice!(range)
      trials = checked_trial!(trials)
      next unless failure.call(candidate.freeze)

      current = candidate
      granularity = [granularity - 1, 2].max
      reduced = true
      break
    end
    next if reduced
    break if granularity >= current.length

    granularity = [granularity * 2, current.length].min
  end

  result(current, trials, true, original_size)
end