z3 0.0.20160427 → 0.0.20161008

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.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +2 -0
  3. data/Rakefile +56 -0
  4. data/examples/bit_tricks +21 -38
  5. data/examples/circuit_problems +170 -0
  6. data/lib/z3/ast.rb +21 -3
  7. data/lib/z3/context.rb +9 -7
  8. data/lib/z3/exception.rb +1 -2
  9. data/lib/z3/expr/arith_expr.rb +29 -11
  10. data/lib/z3/expr/array_expr.rb +5 -0
  11. data/lib/z3/expr/bitvec_expr.rb +293 -13
  12. data/lib/z3/expr/bool_expr.rb +30 -6
  13. data/lib/z3/expr/expr.rb +155 -2
  14. data/lib/z3/expr/float_expr.rb +185 -0
  15. data/lib/z3/expr/int_expr.rb +20 -5
  16. data/lib/z3/expr/real_expr.rb +1 -3
  17. data/lib/z3/expr/rounding_mode_expr.rb +5 -0
  18. data/lib/z3/expr/set_expr.rb +66 -0
  19. data/lib/z3/func_decl.rb +5 -5
  20. data/lib/z3/goal.rb +64 -0
  21. data/lib/z3/interface.rb +21 -222
  22. data/lib/z3/low_level.rb +84 -58
  23. data/lib/z3/low_level_auto.rb +1509 -1563
  24. data/lib/z3/model.rb +39 -37
  25. data/lib/z3/printer.rb +54 -12
  26. data/lib/z3/probe.rb +69 -0
  27. data/lib/z3/solver.rb +20 -20
  28. data/lib/z3/sort/array_sort.rb +24 -0
  29. data/lib/z3/sort/bitvec_sort.rb +1 -1
  30. data/lib/z3/sort/float_sort.rb +92 -0
  31. data/lib/z3/sort/rounding_mode_sort.rb +41 -0
  32. data/lib/z3/sort/set_sort.rb +31 -0
  33. data/lib/z3/sort/sort.rb +39 -5
  34. data/lib/z3/tactic.rb +69 -0
  35. data/lib/z3/very_low_level.rb +33 -29
  36. data/lib/z3/very_low_level_auto.rb +505 -517
  37. data/lib/z3.rb +13 -0
  38. data/spec/array_expr_spec.rb +18 -0
  39. data/spec/array_sort_spec.rb +11 -0
  40. data/spec/bitvec_expr_spec.rb +196 -44
  41. data/spec/bitvec_sort_spec.rb +29 -27
  42. data/spec/bool_expr_spec.rb +57 -55
  43. data/spec/bool_sort_spec.rb +17 -15
  44. data/spec/coverage_helper.rb +11 -0
  45. data/spec/expr_spec.rb +151 -147
  46. data/spec/float_expr_spec.rb +167 -0
  47. data/spec/float_sort_spec.rb +44 -0
  48. data/spec/goal_spec.rb +17 -0
  49. data/spec/int_expr_spec.rb +76 -63
  50. data/spec/int_sort_spec.rb +16 -14
  51. data/spec/integration/algebra_problems_spec.rb +4 -4
  52. data/spec/integration/cicruit_problem_spec.rb +23 -0
  53. data/spec/integration/geometry_problem_spec.rb +4 -4
  54. data/spec/integration/kinematics_problems_spec.rb +3 -3
  55. data/spec/model_spec.rb +39 -37
  56. data/spec/printer_spec.rb +49 -18
  57. data/spec/probe_spec.rb +17 -0
  58. data/spec/real_expr_spec.rb +59 -51
  59. data/spec/real_sort_spec.rb +22 -20
  60. data/spec/rounding_mode_expr_spec.rb +16 -0
  61. data/spec/rounding_mode_sort_spec.rb +13 -0
  62. data/spec/set_expr_spec.rb +61 -0
  63. data/spec/set_sort_spec.rb +27 -0
  64. data/spec/solver_spec.rb +37 -27
  65. data/spec/sort_spec.rb +38 -36
  66. data/spec/spec_helper.rb +59 -2
  67. data/spec/tactic_spec.rb +9 -0
  68. metadata +44 -4
@@ -0,0 +1,13 @@
1
+ module Z3
2
+ describe RoundingModeSort do
3
+ let(:sort) { RoundingModeSort.new }
4
+
5
+ it "to_s" do
6
+ expect(sort.to_s).to eq("RoundingMode")
7
+ end
8
+
9
+ it "inspect" do
10
+ expect(sort.inspect).to eq("RoundingModeSort")
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,61 @@
1
+ module Z3
2
+ describe SetExpr do
3
+ let(:sort) { SetSort.new(IntSort.new) }
4
+ let(:a) { sort.var("a") }
5
+ let(:b) { sort.var("b") }
6
+ let(:c) { sort.var("c") }
7
+ let(:x) { Z3::Bool("x") }
8
+
9
+ # TODO: Formatting is dreadful
10
+ it "== and !=" do
11
+ expect([a == b, b != c]).to have_solution(
12
+ a => "store(const(false), 0, true)",
13
+ b => "store(const(false), 0, true)",
14
+ c => "const(false)",
15
+ )
16
+ end
17
+
18
+ # FIXME: This is not even real spec at this point, just a no-crash-spec
19
+ it "union" do
20
+ expect([
21
+ a.include?(1),
22
+ a.include?(2),
23
+ b.include?(2),
24
+ b.include?(3),
25
+ c == a.union(b),
26
+ ]).to have_solution(
27
+ a => "(declare-fun k! (Int) Bool)",
28
+ b => "(declare-fun k! (Int) Bool)",
29
+ c => "(declare-fun k! (Int) Bool)",
30
+ )
31
+ end
32
+
33
+ it "difference" do
34
+ expect([
35
+ a.include?(1),
36
+ a.include?(2),
37
+ b.include?(2),
38
+ b.include?(3),
39
+ c == a.difference(b),
40
+ ]).to have_solution(
41
+ a => "(declare-fun k! (Int) Bool)",
42
+ b => "(declare-fun k! (Int) Bool)",
43
+ c => "(declare-fun k! (Int) Bool)",
44
+ )
45
+ end
46
+
47
+ it "intersection" do
48
+ expect([
49
+ a.include?(1),
50
+ a.include?(2),
51
+ b.include?(2),
52
+ b.include?(3),
53
+ c == a.intersection(b),
54
+ ]).to have_solution(
55
+ a => "(declare-fun k! (Int) Bool)",
56
+ b => "(declare-fun k! (Int) Bool)",
57
+ c => "(declare-fun k! (Int) Bool)",
58
+ )
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,27 @@
1
+ module Z3
2
+ describe SetSort do
3
+
4
+ let(:int_set) { SetSort.new(IntSort.new) }
5
+ let(:real_set) { SetSort.new(RealSort.new) }
6
+ let(:bool_set) { SetSort.new(BoolSort.new) }
7
+ let(:bv32_set) { SetSort.new(BitvecSort.new(32)) }
8
+ let(:int_set_set) { SetSort.new(SetSort.new(IntSort.new)) }
9
+
10
+ it "can instantiate variables" do
11
+ expect(int_set.var("a").inspect).to eq("Set(Int)<a>")
12
+ expect(real_set.var("a").inspect).to eq("Set(Real)<a>")
13
+ expect(bool_set.var("a").inspect).to eq("Set(Bool)<a>")
14
+ expect(bv32_set.var("a").inspect).to eq("Set(Bitvec(32))<a>")
15
+ expect(int_set_set.var("a").inspect).to eq("Set(Set(Int))<a>")
16
+ end
17
+
18
+ # These are pretty awful formattings
19
+ it "can instantiate full set" do
20
+ expect(int_set.Full.inspect).to eq("Set(Int)<const(true)>")
21
+ end
22
+
23
+ it "can instantiate empty set" do
24
+ expect(int_set.Empty.inspect).to eq("Set(Int)<const(false)>")
25
+ end
26
+ end
27
+ end
data/spec/solver_spec.rb CHANGED
@@ -1,33 +1,43 @@
1
1
  # Solver and Model specs are codependent, so half of functionality of each is tested in other class's tests
2
- describe Z3::Solver do
3
- let(:solver) { Z3::Solver.new }
4
- let(:a) { Z3.Int("a") }
5
- let(:b) { Z3.Int("b") }
2
+ module Z3
3
+ describe Solver do
4
+ let(:solver) { Solver.new }
5
+ let(:a) { Z3.Int("a") }
6
+ let(:b) { Z3.Int("b") }
6
7
 
7
- it "basic functionality" do
8
- solver.assert(a == b)
9
- expect(solver.check).to eq(:sat)
10
- solver.assert(a != b)
11
- expect(solver.check).to eq(:unsat)
12
- end
8
+ it "basic functionality" do
9
+ solver.assert(a == b)
10
+ expect(solver.check).to eq(:sat)
11
+ solver.assert(a != b)
12
+ expect(solver.check).to eq(:unsat)
13
+ end
13
14
 
14
- it "push/pop" do
15
- solver.assert(a == b)
16
- solver.push
17
- solver.assert(a != b)
18
- expect(solver.check).to eq(:unsat)
19
- solver.pop
20
- expect(solver.check).to eq(:sat)
21
- end
15
+ it "push/pop" do
16
+ solver.assert(a == b)
17
+ solver.push
18
+ solver.assert(a != b)
19
+ expect(solver.check).to eq(:unsat)
20
+ solver.pop
21
+ expect(solver.check).to eq(:sat)
22
+ end
23
+
24
+ it "#assertions" do
25
+ solver.assert a + b == 4
26
+ solver.assert b >= 2
27
+ solver.assert Z3.Or(a == 2, a == -2)
28
+ expect(solver.assertions).to be_same_as([
29
+ a + b == 4,
30
+ b >= 2,
31
+ (a == 2) | (a == -2),
32
+ ])
33
+ end
22
34
 
23
- it "#assertions" do
24
- solver.assert a + b == 4
25
- solver.assert b >= 2
26
- solver.assert Z3.Or(a == 2, a == -2)
27
- expect(solver.assertions).to be_same_as([
28
- a + b == 4,
29
- b >= 2,
30
- (a == 2) | (a == -2),
31
- ])
35
+ it "#statistics" do
36
+ solver.assert a + b == 4
37
+ solver.assert b >= 2
38
+ solver.assert Z3.Or(a == 2, a == -2)
39
+ stats = solver.statistics
40
+ expect(stats.keys).to match_array(["rlimit count", "max memory", "memory", "num allocs"])
41
+ end
32
42
  end
33
43
  end
data/spec/sort_spec.rb CHANGED
@@ -1,45 +1,47 @@
1
- describe Z3::Sort do
2
- let(:bool_sort) { Z3::BoolSort.new }
3
- let(:int_sort) { Z3::IntSort.new }
4
- let(:real_sort) { Z3::RealSort.new }
5
- let(:bv8_sort) { Z3::BitvecSort.new(8) }
6
- let(:bv32_sort) { Z3::BitvecSort.new(32) }
1
+ module Z3
2
+ describe Sort do
3
+ let(:bool_sort) { BoolSort.new }
4
+ let(:int_sort) { IntSort.new }
5
+ let(:real_sort) { RealSort.new }
6
+ let(:bv8_sort) { BitvecSort.new(8) }
7
+ let(:bv32_sort) { BitvecSort.new(32) }
7
8
 
8
- let(:sorts) { [bool_sort, int_sort, real_sort, bv8_sort, bv32_sort] }
9
+ let(:sorts) { [bool_sort, int_sort, real_sort, bv8_sort, bv32_sort] }
9
10
 
10
- it "can't instantiate Sort abstract superclass" do
11
- expect{ Z3::Sort.new }.to raise_error(NoMethodError)
12
- end
13
-
14
- it "#to_s" do
15
- expect(bool_sort.to_s).to eq("Bool")
16
- expect( int_sort.to_s).to eq("Int")
17
- expect(real_sort.to_s).to eq("Real")
18
- expect( bv8_sort.to_s).to eq("Bitvec(8)")
19
- expect(bv32_sort.to_s).to eq("Bitvec(32)")
20
- end
11
+ it "can't instantiate Sort abstract superclass" do
12
+ expect{ Sort.new }.to raise_error(NoMethodError)
13
+ end
21
14
 
22
- it "#inspect" do
23
- expect(bool_sort.inspect).to eq("BoolSort")
24
- expect( int_sort.inspect).to eq("IntSort")
25
- expect(real_sort.inspect).to eq("RealSort")
26
- expect( bv8_sort.inspect).to eq("BitvecSort(8)")
27
- expect(bv32_sort.inspect).to eq("BitvecSort(32)")
28
- end
15
+ it "#to_s" do
16
+ expect(bool_sort.to_s).to eq("Bool")
17
+ expect( int_sort.to_s).to eq("Int")
18
+ expect(real_sort.to_s).to eq("Real")
19
+ expect( bv8_sort.to_s).to eq("Bitvec(8)")
20
+ expect(bv32_sort.to_s).to eq("Bitvec(32)")
21
+ end
29
22
 
30
- describe "==" do
31
- it "all Sorts are value-objects" do
32
- expect(bool_sort).to eq( Z3::BoolSort.new )
33
- expect( int_sort).to eq( Z3::IntSort.new )
34
- expect(real_sort).to eq( Z3::RealSort.new )
35
- expect( bv8_sort).to eq( Z3::BitvecSort.new(8) )
36
- expect(bv32_sort).to eq( Z3::BitvecSort.new(32) )
23
+ it "#inspect" do
24
+ expect(bool_sort.inspect).to eq("BoolSort")
25
+ expect( int_sort.inspect).to eq("IntSort")
26
+ expect(real_sort.inspect).to eq("RealSort")
27
+ expect( bv8_sort.inspect).to eq("BitvecSort(8)")
28
+ expect(bv32_sort.inspect).to eq("BitvecSort(32)")
37
29
  end
38
30
 
39
- it "is == to itself and no other sort" do
40
- sorts.each do |sort1|
41
- sorts.each do |sort2|
42
- expect(sort1 == sort2).to eq(sort1.to_s == sort2.to_s)
31
+ describe "==" do
32
+ it "all Sorts are value-objects" do
33
+ expect(bool_sort).to eq( BoolSort.new )
34
+ expect( int_sort).to eq( IntSort.new )
35
+ expect(real_sort).to eq( RealSort.new )
36
+ expect( bv8_sort).to eq( BitvecSort.new(8) )
37
+ expect(bv32_sort).to eq( BitvecSort.new(32) )
38
+ end
39
+
40
+ it "is == to itself and no other sort" do
41
+ sorts.each do |sort1|
42
+ sorts.each do |sort2|
43
+ expect(sort1 == sort2).to eq(sort1.to_s == sort2.to_s)
44
+ end
43
45
  end
44
46
  end
45
47
  end
data/spec/spec_helper.rb CHANGED
@@ -2,7 +2,9 @@ require "pry"
2
2
 
3
3
  if ENV["COVERAGE"]
4
4
  require 'simplecov'
5
- SimpleCov.start
5
+ SimpleCov.start do
6
+ add_filter "/spec/"
7
+ end
6
8
  end
7
9
 
8
10
  require_relative "../lib/z3"
@@ -36,7 +38,7 @@ end
36
38
  RSpec::Matchers.define :have_output do |expected|
37
39
  match do |file_name|
38
40
  executable_path = "#{__dir__}/../examples/#{file_name}"
39
- actual = IO.popen(executable_path).read
41
+ actual = IO.popen("ruby -r./spec/coverage_helper #{executable_path}").read
40
42
  actual.gsub(/ *$/, "") == expected.gsub(/ *$/, "")
41
43
  end
42
44
  end
@@ -47,10 +49,26 @@ RSpec::Matchers.define :be_same_as do |expected|
47
49
  end
48
50
  end
49
51
 
52
+ RSpec::Matchers.define :be_all_same do
53
+ match do |array|
54
+ array.uniq.size == 1
55
+ end
56
+ end
57
+
58
+ RSpec::Matchers.define :be_all_different do
59
+ match do |array|
60
+ array.uniq.size == array.size
61
+ end
62
+ end
63
+
50
64
  RSpec::Matchers.define :stringify do |expected|
51
65
  match do |actual|
52
66
  actual.to_s == expected
53
67
  end
68
+
69
+ failure_message do
70
+ "Expected #{actual.inspect} to stringify to `#{expected}', got `#{actual.to_s}' instead"
71
+ end
54
72
  end
55
73
 
56
74
  RSpec::Matchers.define :have_solution do |expected|
@@ -76,3 +94,42 @@ RSpec::Matchers.define :have_solution do |expected|
76
94
  end
77
95
  end
78
96
  end
97
+
98
+ RSpec::Matchers.define :have_solutions do |expected|
99
+ match do |asts|
100
+ solutions = get_all_solutions(asts)
101
+ solutions == expected
102
+ end
103
+
104
+ failure_message do |asts|
105
+ solutions = get_all_solutions(asts)
106
+ "expected #{asts.inspect} to have solutions:\n#{expected.map{|s| "* #{s.inspect}\n"}.join}, instead got:\n#{solutions.map{|s| "* #{s.inspect}\n"}.join}"
107
+ end
108
+
109
+ def get_all_solutions(asts)
110
+ vars = expected.map(&:keys)
111
+ raise "All expectations need same set of keys" unless vars.uniq.size == 1
112
+ vars = vars[0]
113
+ solver = setup_solver(asts)
114
+ solutions = []
115
+ while solver.check == :sat
116
+ model = solver.model
117
+ solution = Hash[vars.map{|v| [v, model.model_eval(v, true)] }]
118
+ solutions << solution
119
+ solver.assert Z3.Or(*solution.map{|var,val| var != val})
120
+ if solutions.size >= 10
121
+ binding.pry
122
+ raise "Too many solutions found, presumably infinite loop"
123
+ end
124
+ end
125
+ solutions
126
+ end
127
+
128
+ def setup_solver(asts)
129
+ Z3::Solver.new.tap do |solver|
130
+ asts.each do |ast|
131
+ solver.assert ast
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,9 @@
1
+ module Z3
2
+ describe Tactic do
3
+ it "constructors" do
4
+ expect(Tactic.fail).to be_a Tactic
5
+ expect(Tactic.fail_if_not_decided).to be_a Tactic
6
+ expect(Tactic.skip).to be_a Tactic
7
+ end
8
+ end
9
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: z3
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.20160427
4
+ version: 0.0.20161008
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomasz Wegrzanowski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-27 00:00:00.000000000 Z
11
+ date: 2016-10-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rspec
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -72,13 +86,16 @@ executables: []
72
86
  extensions: []
73
87
  extra_rdoc_files: []
74
88
  files:
89
+ - ".rspec"
75
90
  - README.md
91
+ - Rakefile
76
92
  - examples/algebra_problems
77
93
  - examples/basic_int_math
78
94
  - examples/basic_logic
79
95
  - examples/bit_tricks
80
96
  - examples/bridges
81
97
  - examples/bridges-1.txt
98
+ - examples/circuit_problems
82
99
  - examples/clogic_puzzle
83
100
  - examples/four_hackers_puzzle
84
101
  - examples/geometry_problem
@@ -102,30 +119,47 @@ files:
102
119
  - lib/z3/context.rb
103
120
  - lib/z3/exception.rb
104
121
  - lib/z3/expr/arith_expr.rb
122
+ - lib/z3/expr/array_expr.rb
105
123
  - lib/z3/expr/bitvec_expr.rb
106
124
  - lib/z3/expr/bool_expr.rb
107
125
  - lib/z3/expr/expr.rb
126
+ - lib/z3/expr/float_expr.rb
108
127
  - lib/z3/expr/int_expr.rb
109
128
  - lib/z3/expr/real_expr.rb
129
+ - lib/z3/expr/rounding_mode_expr.rb
130
+ - lib/z3/expr/set_expr.rb
110
131
  - lib/z3/func_decl.rb
132
+ - lib/z3/goal.rb
111
133
  - lib/z3/interface.rb
112
134
  - lib/z3/low_level.rb
113
135
  - lib/z3/low_level_auto.rb
114
136
  - lib/z3/model.rb
115
137
  - lib/z3/printer.rb
138
+ - lib/z3/probe.rb
116
139
  - lib/z3/solver.rb
140
+ - lib/z3/sort/array_sort.rb
117
141
  - lib/z3/sort/bitvec_sort.rb
118
142
  - lib/z3/sort/bool_sort.rb
143
+ - lib/z3/sort/float_sort.rb
119
144
  - lib/z3/sort/int_sort.rb
120
145
  - lib/z3/sort/real_sort.rb
146
+ - lib/z3/sort/rounding_mode_sort.rb
147
+ - lib/z3/sort/set_sort.rb
121
148
  - lib/z3/sort/sort.rb
149
+ - lib/z3/tactic.rb
122
150
  - lib/z3/very_low_level.rb
123
151
  - lib/z3/very_low_level_auto.rb
152
+ - spec/array_expr_spec.rb
153
+ - spec/array_sort_spec.rb
124
154
  - spec/bitvec_expr_spec.rb
125
155
  - spec/bitvec_sort_spec.rb
126
156
  - spec/bool_expr_spec.rb
127
157
  - spec/bool_sort_spec.rb
158
+ - spec/coverage_helper.rb
128
159
  - spec/expr_spec.rb
160
+ - spec/float_expr_spec.rb
161
+ - spec/float_sort_spec.rb
162
+ - spec/goal_spec.rb
129
163
  - spec/int_expr_spec.rb
130
164
  - spec/int_sort_spec.rb
131
165
  - spec/integration/algebra_problems_spec.rb
@@ -133,6 +167,7 @@ files:
133
167
  - spec/integration/basic_logic_spec.rb
134
168
  - spec/integration/bit_tricks_spec.rb
135
169
  - spec/integration/bridges_spec.rb
170
+ - spec/integration/cicruit_problem_spec.rb
136
171
  - spec/integration/four_hackers_puzzle_spec.rb
137
172
  - spec/integration/geometry_problem_spec.rb
138
173
  - spec/integration/kakuro_spec.rb
@@ -147,11 +182,17 @@ files:
147
182
  - spec/integration/verbal_arithmetic_spec.rb
148
183
  - spec/model_spec.rb
149
184
  - spec/printer_spec.rb
185
+ - spec/probe_spec.rb
150
186
  - spec/real_expr_spec.rb
151
187
  - spec/real_sort_spec.rb
188
+ - spec/rounding_mode_expr_spec.rb
189
+ - spec/rounding_mode_sort_spec.rb
190
+ - spec/set_expr_spec.rb
191
+ - spec/set_sort_spec.rb
152
192
  - spec/solver_spec.rb
153
193
  - spec/sort_spec.rb
154
194
  - spec/spec_helper.rb
195
+ - spec/tactic_spec.rb
155
196
  - spec/z3_spec.rb
156
197
  homepage: https://github.com/taw/z3
157
198
  licenses:
@@ -174,9 +215,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
174
215
  requirements:
175
216
  - z3 library
176
217
  rubyforge_project:
177
- rubygems_version: 2.4.5
218
+ rubygems_version: 2.5.1
178
219
  signing_key:
179
220
  specification_version: 4
180
221
  summary: Z3 Constraint Solver
181
222
  test_files: []
182
- has_rdoc: