dither 0.1.5-java → 0.2.0-java
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +6 -1
- data/README.md +3 -0
- data/Rakefile +4 -0
- data/dither.gemspec +5 -1
- data/ext/dither/README.md +2 -0
- data/ext/dither/base_constraint_handler.h +36 -0
- data/ext/dither/combinations.h +127 -0
- data/ext/dither/dither.cc +47 -0
- data/ext/dither/dither.h +31 -0
- data/ext/dither/dither_types.h +32 -0
- data/ext/dither/extconf.rb +4 -0
- data/ext/dither/ipog.cc +451 -0
- data/ext/dither/ipog.h +128 -0
- data/ext/dither/simple_constraint_handler.cc +105 -0
- data/ext/dither/simple_constraint_handler.h +39 -0
- data/lib/dither/api.rb +21 -0
- data/lib/dither/version.rb +1 -1
- data/lib/{dither-0.1.3.jar → dither-0.1.4.jar} +0 -0
- data/lib/dither.rb +65 -14
- data/spec/dither/dither_spec.rb +28 -97
- metadata +42 -22
- data/lib/dither/ipog.rb +0 -58
- data/lib/dither/ipog_helper.rb +0 -161
- data/lib/dither/mipog.rb +0 -85
- data/lib/dither/param.rb +0 -19
- data/lib/dither/test_case.rb +0 -80
- data/lib/dither/unbound_param.rb +0 -17
data/lib/dither/ipog_helper.rb
DELETED
@@ -1,161 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
module Dither
|
4
|
-
module IPOGHelper
|
5
|
-
attr_reader :params, :t, :constraints, :test_set, :orig_params, :unbound_param_pool, :tested
|
6
|
-
private :params, :t, :constraints, :test_set, :orig_params, :unbound_param_pool, :tested
|
7
|
-
|
8
|
-
def initialize(params, opts = {})
|
9
|
-
init_params(params, (opts[:previously_tested] || []))
|
10
|
-
@t = opts[:t]
|
11
|
-
unless opts[:constraints].nil?
|
12
|
-
@constraints = opts[:constraints].map(&:to_a)
|
13
|
-
.map { |a| a.map { |b| @params[@map_to_orig_index.key(b[0])][b[1]] } }
|
14
|
-
.map(&:to_set)
|
15
|
-
end
|
16
|
-
|
17
|
-
raise Dither::Error, 't must be >= 2' if opts[:t] < 2
|
18
|
-
raise Dither::Error, 't must be <= params.length' if opts[:t] > params.length
|
19
|
-
params.each do |param|
|
20
|
-
raise Dither::Error, 'param length must be > 1' if param.length < 2
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def init_params(user_params, previously_tested)
|
25
|
-
tmp = []
|
26
|
-
@input_params = user_params
|
27
|
-
user_params.each_with_index { |e, i| tmp << [i, e] }
|
28
|
-
@orig_params = tmp.sort_by { |a| a[1].length }
|
29
|
-
.reverse!
|
30
|
-
|
31
|
-
orig_param_map = {}
|
32
|
-
@map_to_orig_index = {}
|
33
|
-
@orig_params.each_with_index do |e, i|
|
34
|
-
@map_to_orig_index[i] = e[0]
|
35
|
-
orig_param_map[e[0]] = {}
|
36
|
-
end
|
37
|
-
|
38
|
-
@params = []
|
39
|
-
@unbound_param_pool = []
|
40
|
-
orig_params.each_with_index do |e, i|
|
41
|
-
@params << (0...e[1].length).map do |j|
|
42
|
-
local_param = Param.new(i, j)
|
43
|
-
orig_param_map[e[0]][e[1][j]] = local_param
|
44
|
-
local_param
|
45
|
-
end
|
46
|
-
@unbound_param_pool << UnboundParam.new(i)
|
47
|
-
end
|
48
|
-
|
49
|
-
@tested = []
|
50
|
-
previously_tested.each do |a|
|
51
|
-
local_params = []
|
52
|
-
a.each_with_index do |e, i|
|
53
|
-
local_params << orig_param_map[i][e]
|
54
|
-
end
|
55
|
-
@tested << TestCase.create(params, unbound_param_pool, local_params)
|
56
|
-
end
|
57
|
-
|
58
|
-
params
|
59
|
-
end
|
60
|
-
|
61
|
-
# return nil if unable to satisfy constraints
|
62
|
-
def maximize_coverage(i, test_case, pi)
|
63
|
-
current_max = 0
|
64
|
-
current_max_j = 0
|
65
|
-
current_matches = []
|
66
|
-
|
67
|
-
(0...params[i].length).each do |j|
|
68
|
-
current_param = params[i][j]
|
69
|
-
test_case << current_param
|
70
|
-
unless violates_constraints?(test_case)
|
71
|
-
matches = pi.select { |a| a.subset?(test_case) }
|
72
|
-
count = matches.count
|
73
|
-
|
74
|
-
if count > current_max
|
75
|
-
current_max = count
|
76
|
-
current_max_j = j
|
77
|
-
current_matches = matches
|
78
|
-
end
|
79
|
-
end
|
80
|
-
test_case.delete(current_param)
|
81
|
-
end
|
82
|
-
|
83
|
-
return nil if violates_constraints?(test_case)
|
84
|
-
test_case << params[i][current_max_j]
|
85
|
-
|
86
|
-
current_matches
|
87
|
-
end
|
88
|
-
|
89
|
-
def violates_constraints?(params)
|
90
|
-
return false if constraints.nil?
|
91
|
-
constraints.any? { |b| b.subset?(params) }
|
92
|
-
end
|
93
|
-
|
94
|
-
private
|
95
|
-
|
96
|
-
def comb
|
97
|
-
ranges = (0...t).to_a.inject([]) do |a, i|
|
98
|
-
a << (0...params[i].length).map { |j| params[i][j] }
|
99
|
-
end
|
100
|
-
|
101
|
-
products = ranges[1..-1].inject(ranges[0]) do |a, b|
|
102
|
-
a = a.product(b)
|
103
|
-
end
|
104
|
-
|
105
|
-
result = products.map(&:flatten)
|
106
|
-
.map { |a| TestCase.create(params, unbound_param_pool, a) }
|
107
|
-
result.reject { |a| tested?(a) }
|
108
|
-
end
|
109
|
-
|
110
|
-
def comb_i(param_i)
|
111
|
-
values = (0...param_i).to_a.combination((t-1)).to_a
|
112
|
-
values.each do |a|
|
113
|
-
a << param_i
|
114
|
-
end
|
115
|
-
result = []
|
116
|
-
values.each do |a|
|
117
|
-
result += a[1..-1]
|
118
|
-
.inject((0...params[a[0]].length).map { |b| params[a[0]][b] }) { |p, i| p.product((0...params[i].length).to_a.map { |c| params[i][c] }) }
|
119
|
-
.map(&:flatten)
|
120
|
-
.map { |b| TestCase.create(params, unbound_param_pool, b) }
|
121
|
-
end
|
122
|
-
result.reject { |a| tested?(a) }.to_set
|
123
|
-
end
|
124
|
-
|
125
|
-
def tested?(test_case)
|
126
|
-
@tested.any? { |a| test_case.subset?(a) }
|
127
|
-
end
|
128
|
-
|
129
|
-
def fill_unbound(data)
|
130
|
-
arr = Array.new(params.length)
|
131
|
-
data.each do |param|
|
132
|
-
unless param.unbound?
|
133
|
-
i = @map_to_orig_index[param.i]
|
134
|
-
arr[i] = @input_params[i][param.j]
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
arr.each_with_index do |e, i|
|
139
|
-
next unless e.nil?
|
140
|
-
|
141
|
-
orig_param = @input_params[i]
|
142
|
-
(0...orig_param.length).each do |j|
|
143
|
-
data << params[@map_to_orig_index.key(i)][j]
|
144
|
-
if violates_constraints?(data)
|
145
|
-
data.delete(params[@map_to_orig_index.key(i)][j])
|
146
|
-
next
|
147
|
-
else
|
148
|
-
arr[i] = orig_param[j]
|
149
|
-
break
|
150
|
-
end
|
151
|
-
end
|
152
|
-
return nil if arr[i].nil?
|
153
|
-
end
|
154
|
-
|
155
|
-
return nil if violates_constraints?(data)
|
156
|
-
return nil if tested?(data)
|
157
|
-
|
158
|
-
arr
|
159
|
-
end
|
160
|
-
end # IPOGHelper
|
161
|
-
end # Dither
|
data/lib/dither/mipog.rb
DELETED
@@ -1,85 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
module Dither
|
4
|
-
class MIPOG
|
5
|
-
include Dither::IPOGHelper
|
6
|
-
|
7
|
-
def maximize_unbound_coverage(i, test_case, pi)
|
8
|
-
all_unbound = test_case.unbound
|
9
|
-
.map { |a| a.create_params(params[a.i].length) }
|
10
|
-
.flatten
|
11
|
-
|
12
|
-
current_max = 0
|
13
|
-
current_max_j = 0
|
14
|
-
current_outer_param = all_unbound[0]
|
15
|
-
current_matches = []
|
16
|
-
|
17
|
-
all_unbound.each do |outer_param|
|
18
|
-
test_case << outer_param
|
19
|
-
|
20
|
-
(0...params[i].length).each do |j|
|
21
|
-
current_param = params[i][j]
|
22
|
-
test_case << current_param
|
23
|
-
count = pi.count { |a| a.subset?(test_case) }
|
24
|
-
|
25
|
-
if count > current_max
|
26
|
-
current_max = count
|
27
|
-
current_max_j = j
|
28
|
-
current_outer_param = outer_param
|
29
|
-
end
|
30
|
-
test_case.delete(current_param)
|
31
|
-
end
|
32
|
-
test_case.delete(outer_param)
|
33
|
-
end
|
34
|
-
|
35
|
-
test_case << params[i][current_max_j]
|
36
|
-
test_case << current_outer_param
|
37
|
-
test_case.delete(unbound_param_pool[current_outer_param.i])
|
38
|
-
|
39
|
-
current_matches
|
40
|
-
end
|
41
|
-
|
42
|
-
def run
|
43
|
-
# add into test set a test for each combination of values
|
44
|
-
# of the first t parameter
|
45
|
-
test_set = comb
|
46
|
-
|
47
|
-
(t...params.length).each do |i|
|
48
|
-
# let pi
|
49
|
-
# be the set of t-way combinations of values involving
|
50
|
-
# parameter Pi and t -1 parameters among the first i – 1
|
51
|
-
# parameters
|
52
|
-
pi = comb_i(i)
|
53
|
-
|
54
|
-
# horizontal extension for parameter i
|
55
|
-
test_set.each do |test_case|
|
56
|
-
if !test_case.contains_unbound?
|
57
|
-
cover = maximize_coverage(i, test_case, pi)
|
58
|
-
else
|
59
|
-
cover = maximize_unbound_coverage(i, test_case, pi)
|
60
|
-
end
|
61
|
-
|
62
|
-
# remove covered combinations
|
63
|
-
pi -= cover
|
64
|
-
end
|
65
|
-
|
66
|
-
# vertical extension for parameter i
|
67
|
-
until pi.empty?
|
68
|
-
pi.sort!
|
69
|
-
test_case, coverage = maximize_vertical_coverage(i, pi[0].dup, pi)
|
70
|
-
test_set << test_case.create_unbound(i)
|
71
|
-
pi -= coverage
|
72
|
-
end
|
73
|
-
end
|
74
|
-
test_set.map { |a| fill_unbound(a) }
|
75
|
-
end
|
76
|
-
|
77
|
-
def maximize_vertical_coverage(i, test_case, pi)
|
78
|
-
coverage = [pi[0]]
|
79
|
-
pi[1..-1].each do |a|
|
80
|
-
coverage << a unless test_case.merge_without_conflict(i, a).nil?
|
81
|
-
end
|
82
|
-
[test_case, coverage]
|
83
|
-
end
|
84
|
-
end # MIPOG
|
85
|
-
end # Dither
|
data/lib/dither/param.rb
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
|
2
|
-
module Dither
|
3
|
-
Param = Struct.new(:i, :j) do
|
4
|
-
def <=>(param)
|
5
|
-
return 1 if param.unbound?
|
6
|
-
|
7
|
-
a = i <=> param.i
|
8
|
-
if a == 0
|
9
|
-
return j <=> param.j
|
10
|
-
else
|
11
|
-
return a
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
def unbound?
|
16
|
-
false
|
17
|
-
end
|
18
|
-
end # Param
|
19
|
-
end # Dither
|
data/lib/dither/test_case.rb
DELETED
@@ -1,80 +0,0 @@
|
|
1
|
-
|
2
|
-
module Dither
|
3
|
-
class TestCase < Set
|
4
|
-
|
5
|
-
attr_accessor :bound_param_pool, :unbound_param_pool
|
6
|
-
|
7
|
-
def self.create(bound_param_pool, unbound_param_pool, params)
|
8
|
-
test_case = TestCase.new(params)
|
9
|
-
test_case.bound_param_pool = bound_param_pool
|
10
|
-
test_case.unbound_param_pool = unbound_param_pool
|
11
|
-
test_case
|
12
|
-
end
|
13
|
-
|
14
|
-
def contains_unbound?
|
15
|
-
self.any?(&:unbound?)
|
16
|
-
end
|
17
|
-
|
18
|
-
def unbound
|
19
|
-
self.select(&:unbound?)
|
20
|
-
end
|
21
|
-
|
22
|
-
def <=>(test_case)
|
23
|
-
result = 0
|
24
|
-
l = length <= test_case.length ? length : test_case.length
|
25
|
-
self.zip(test_case)[0...l].each do |arr|
|
26
|
-
first, second = arr
|
27
|
-
result = first <=> second
|
28
|
-
break if result != 0
|
29
|
-
end
|
30
|
-
result
|
31
|
-
end
|
32
|
-
|
33
|
-
def create_unbound(i)
|
34
|
-
bound_params = self.reject(&:unbound?).map(&:i)
|
35
|
-
((0..i).to_a - bound_params).each do |a|
|
36
|
-
self << unbound_param_pool[a]
|
37
|
-
end
|
38
|
-
self
|
39
|
-
end
|
40
|
-
|
41
|
-
def to_ipog_array(i)
|
42
|
-
arr = Array.new(i)
|
43
|
-
self.each do |param|
|
44
|
-
arr[param.i] = param.j unless param.unbound?
|
45
|
-
end
|
46
|
-
arr
|
47
|
-
end
|
48
|
-
|
49
|
-
# return nil if there is a conflict
|
50
|
-
# return self if no conflict
|
51
|
-
def merge_without_conflict(i, test_case, &block)
|
52
|
-
new_elements = []
|
53
|
-
self.to_ipog_array(i).zip(test_case.to_ipog_array(i))
|
54
|
-
.each_with_index do |arr, a|
|
55
|
-
first, second = arr
|
56
|
-
|
57
|
-
if first.nil? && second.nil?
|
58
|
-
new_elements << unbound_param_pool[a]
|
59
|
-
elsif (first == second) || second.nil?
|
60
|
-
next
|
61
|
-
elsif first.nil?
|
62
|
-
new_elements << bound_param_pool[a][second]
|
63
|
-
else
|
64
|
-
return nil
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
new_self = self.clone
|
69
|
-
new_elements.each { |a| new_self << a }
|
70
|
-
|
71
|
-
return nil if block_given? && block.call(new_self)
|
72
|
-
|
73
|
-
new_elements.each do |a|
|
74
|
-
self.delete(unbound_param_pool[a.i]) unless a.unbound?
|
75
|
-
self << a
|
76
|
-
end
|
77
|
-
self
|
78
|
-
end
|
79
|
-
end # TestCase
|
80
|
-
end # Dither
|
data/lib/dither/unbound_param.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
|
2
|
-
module Dither
|
3
|
-
UnboundParam = Struct.new(:i) do
|
4
|
-
def <=>(param)
|
5
|
-
return -1 unless param.unbound?
|
6
|
-
i <=> param.i
|
7
|
-
end
|
8
|
-
|
9
|
-
def unbound?
|
10
|
-
true
|
11
|
-
end
|
12
|
-
|
13
|
-
def create_params(j)
|
14
|
-
(0...j).map { |a| Param.new(i, a) }
|
15
|
-
end
|
16
|
-
end # UnboundParam
|
17
|
-
end # Dither
|