z3 0.0.20180624 → 0.0.20211213

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 (115) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -4
  3. data/Rakefile +15 -8
  4. data/examples/abc_path +187 -0
  5. data/examples/abc_path-1.txt +7 -0
  6. data/examples/algebra_problems +12 -12
  7. data/examples/aquarium +133 -0
  8. data/examples/aquarium-1.txt +11 -0
  9. data/examples/bridges +2 -2
  10. data/examples/cats_organized_neatly +133 -0
  11. data/examples/cats_organized_neatly-10.txt +15 -0
  12. data/examples/cats_organized_neatly-3.txt +8 -0
  13. data/examples/cats_organized_neatly-48.txt +32 -0
  14. data/examples/circuit_problems +4 -4
  15. data/examples/clogic_puzzle +2 -2
  16. data/examples/color_nonogram +150 -0
  17. data/examples/color_nonogram-1.txt +23 -0
  18. data/examples/crossflip +2 -4
  19. data/examples/dominion +153 -0
  20. data/examples/dominion-1.txt +8 -0
  21. data/examples/dominosa +133 -0
  22. data/examples/dominosa-1.txt +8 -0
  23. data/examples/eulero +99 -0
  24. data/examples/eulero-1.txt +5 -0
  25. data/examples/four_hackers_puzzle +2 -2
  26. data/examples/futoshiki +128 -0
  27. data/examples/futoshiki-1.txt +17 -0
  28. data/examples/kakurasu +73 -0
  29. data/examples/kakurasu-1.txt +2 -0
  30. data/examples/kakuro +2 -2
  31. data/examples/killer_sudoku +88 -0
  32. data/examples/killer_sudoku-1.txt +17 -0
  33. data/examples/killer_sudoku-2.txt +53 -0
  34. data/examples/kinematics_problems +20 -20
  35. data/examples/knights_puzzle +2 -2
  36. data/examples/kropki +100 -0
  37. data/examples/kropki-1.txt +13 -0
  38. data/examples/letter_connections +2 -2
  39. data/examples/light_up +2 -2
  40. data/examples/minisudoku +2 -2
  41. data/examples/miracle_sudoku +135 -0
  42. data/examples/miracle_sudoku-1.txt +9 -0
  43. data/examples/mortal_coil_puzzle +2 -2
  44. data/examples/nanro +245 -0
  45. data/examples/nanro-1.txt +8 -0
  46. data/examples/nine_clocks +106 -0
  47. data/examples/nonogram +2 -2
  48. data/examples/pyramid_nonogram +2 -2
  49. data/examples/regexp_crossword_solver +2 -2
  50. data/examples/regexp_solver +2 -2
  51. data/examples/renzoku +124 -0
  52. data/examples/renzoku-1.txt +17 -0
  53. data/examples/sandwich_sudoku +101 -0
  54. data/examples/sandwich_sudoku-1.txt +10 -0
  55. data/examples/selfref +2 -2
  56. data/examples/simple_regexp_parser.rb +58 -56
  57. data/examples/skyscrapers +118 -0
  58. data/examples/skyscrapers-1.txt +6 -0
  59. data/examples/skyscrapers-2.txt +11 -0
  60. data/examples/star_battle +134 -0
  61. data/examples/star_battle-1.txt +10 -0
  62. data/examples/stitches +180 -0
  63. data/examples/stitches-1.txt +11 -0
  64. data/examples/sudoku +2 -2
  65. data/examples/suguru +199 -0
  66. data/examples/suguru-1.txt +17 -0
  67. data/examples/verbal_arithmetic +2 -2
  68. data/examples/yajilin +268 -0
  69. data/examples/yajilin-1.txt +10 -0
  70. data/lib/z3/ast.rb +8 -0
  71. data/lib/z3/expr/bitvec_expr.rb +10 -0
  72. data/lib/z3/expr/expr.rb +16 -15
  73. data/lib/z3/low_level.rb +6 -2
  74. data/lib/z3/low_level_auto.rb +180 -36
  75. data/lib/z3/optimize.rb +5 -4
  76. data/lib/z3/printer.rb +29 -1
  77. data/lib/z3/sort/bitvec_sort.rb +1 -0
  78. data/lib/z3/sort/sort.rb +9 -5
  79. data/lib/z3/very_low_level.rb +8 -5
  80. data/lib/z3/very_low_level_auto.rb +45 -9
  81. data/spec/bitvec_expr_spec.rb +35 -21
  82. data/spec/bitvec_sort_spec.rb +4 -0
  83. data/spec/expr_spec.rb +62 -0
  84. data/spec/integration/abc_path_spec.rb +21 -0
  85. data/spec/integration/aquarium_spec.rb +27 -0
  86. data/spec/integration/cats_organized_neatly_spec.rb +14 -0
  87. data/spec/integration/color_nonogram_spec.rb +28 -0
  88. data/spec/integration/dominion_spec.rb +14 -0
  89. data/spec/integration/dominosa_spec.rb +21 -0
  90. data/spec/integration/eulero_spec.rb +11 -0
  91. data/spec/integration/futoshiki_spec.rb +23 -0
  92. data/spec/integration/kakurasu_spec.rb +18 -0
  93. data/spec/integration/killer_sudoku_spec.rb +10 -0
  94. data/spec/integration/knights_puzzle_spec.rb +11 -11
  95. data/spec/integration/kropki_spec.rb +19 -0
  96. data/spec/integration/miracle_sudoku_spec.rb +15 -0
  97. data/spec/integration/mortal_coil_puzzle_spec.rb +8 -6
  98. data/spec/integration/nanro_spec.rb +39 -0
  99. data/spec/integration/nine_clocks_spec.rb +30 -0
  100. data/spec/integration/oneofus_spec.rb +7 -15
  101. data/spec/integration/regexp_crossword_solver_spec.rb +1 -1
  102. data/spec/integration/renzoku_spec.rb +23 -0
  103. data/spec/integration/sandwich_sudoku_spec.rb +15 -0
  104. data/spec/integration/skyscraper_spec.rb +10 -0
  105. data/spec/integration/star_battle_spec.rb +27 -0
  106. data/spec/integration/stitches_spec.rb +25 -0
  107. data/spec/integration/suguru_spec.rb +23 -0
  108. data/spec/integration/yajilin_spec.rb +25 -0
  109. data/spec/interface_spec.rb +18 -0
  110. data/spec/optimize_spec.rb +6 -4
  111. data/spec/printer_spec.rb +30 -0
  112. data/spec/set_expr_spec.rb +14 -8
  113. data/spec/solver_spec.rb +4 -5
  114. data/spec/spec_helper.rb +15 -0
  115. metadata +104 -24
@@ -1,6 +1,7 @@
1
1
  module Z3
2
2
  class BitvecSort < Sort
3
3
  def initialize(n)
4
+ raise Z3::Exception, "Bitvec width must be positive" unless n >= 1
4
5
  super LowLevel.mk_bv_sort(n)
5
6
  end
6
7
 
data/lib/z3/sort/sort.rb CHANGED
@@ -57,12 +57,16 @@ module Z3
57
57
  end
58
58
 
59
59
  def var(name)
60
- new(
61
- LowLevel.mk_const(
62
- LowLevel.mk_string_symbol(name),
63
- self,
60
+ if name.is_a?(Enumerable)
61
+ name.map{|v| var(v)}
62
+ else
63
+ new(
64
+ LowLevel.mk_const(
65
+ LowLevel.mk_string_symbol(name),
66
+ self,
67
+ )
64
68
  )
65
- )
69
+ end
66
70
  end
67
71
 
68
72
  # We pretend to be a class, sort of
@@ -1,19 +1,21 @@
1
1
  # Seriously do not use this directly in your code
2
-
3
- require 'ffi'
2
+ require "ffi"
4
3
 
5
4
  module Z3
6
5
  module VeryLowLevel
7
6
  extend FFI::Library
8
- ffi_lib "z3"
7
+ ffi_lib ["libz3.so.4.8", "libz3.so", "z3"]
9
8
 
10
9
  class << self
11
10
  # Aliases defined just to make APIs below look nicer
12
11
  def attach_function(name, arg_types, return_type)
13
-
14
- arg_types = arg_types.map{|t| map_type(t)}
12
+ arg_types = arg_types.map { |t| map_type(t) }
15
13
  return_type = map_type(return_type)
16
14
  super(name, arg_types, return_type)
15
+ rescue FFI::NotFoundError
16
+ define_singleton_method(name) do |*args|
17
+ raise Z3::Exception, "Could not find #{name} in the Z3 library. It is likely that the Z3 library has wrong version."
18
+ end
17
19
  end
18
20
 
19
21
  def map_type(t)
@@ -40,5 +42,6 @@ module Z3
40
42
  attach_function :Z3_mk_set_union, [:ctx_pointer, :int, :pointer], :ast_pointer
41
43
  attach_function :Z3_mk_set_intersect, [:ctx_pointer, :int, :pointer], :ast_pointer
42
44
  attach_function :Z3_mk_distinct, [:ctx_pointer, :int, :pointer], :ast_pointer
45
+ attach_function :Z3_optimize_check, [:ctx_pointer, :optimize_pointer, :int, :pointer], :int
43
46
  end
44
47
  end
@@ -6,6 +6,8 @@ module Z3
6
6
  attach_function :Z3_algebraic_div, [:ctx_pointer, :ast_pointer, :ast_pointer], :ast_pointer
7
7
  attach_function :Z3_algebraic_eq, [:ctx_pointer, :ast_pointer, :ast_pointer], :bool
8
8
  attach_function :Z3_algebraic_ge, [:ctx_pointer, :ast_pointer, :ast_pointer], :bool
9
+ attach_function :Z3_algebraic_get_i, [:ctx_pointer, :ast_pointer], :uint
10
+ attach_function :Z3_algebraic_get_poly, [:ctx_pointer, :ast_pointer], :ast_vector_pointer
9
11
  attach_function :Z3_algebraic_gt, [:ctx_pointer, :ast_pointer, :ast_pointer], :bool
10
12
  attach_function :Z3_algebraic_is_neg, [:ctx_pointer, :ast_pointer], :bool
11
13
  attach_function :Z3_algebraic_is_pos, [:ctx_pointer, :ast_pointer], :bool
@@ -19,7 +21,6 @@ module Z3
19
21
  attach_function :Z3_algebraic_root, [:ctx_pointer, :ast_pointer, :uint], :ast_pointer
20
22
  attach_function :Z3_algebraic_sign, [:ctx_pointer, :ast_pointer], :int
21
23
  attach_function :Z3_algebraic_sub, [:ctx_pointer, :ast_pointer, :ast_pointer], :ast_pointer
22
- attach_function :Z3_apply_result_convert_model, [:ctx_pointer, :apply_result_pointer, :uint, :model_pointer], :model_pointer
23
24
  attach_function :Z3_apply_result_dec_ref, [:ctx_pointer, :apply_result_pointer], :void
24
25
  attach_function :Z3_apply_result_get_num_subgoals, [:ctx_pointer, :apply_result_pointer], :uint
25
26
  attach_function :Z3_apply_result_get_subgoal, [:ctx_pointer, :apply_result_pointer, :uint], :goal_pointer
@@ -53,6 +54,7 @@ module Z3
53
54
  attach_function :Z3_del_context, [:ctx_pointer], :void
54
55
  attach_function :Z3_disable_trace, [:string], :void
55
56
  attach_function :Z3_enable_trace, [:string], :void
57
+ attach_function :Z3_eval_smtlib2_string, [:ctx_pointer, :string], :string
56
58
  attach_function :Z3_finalize_memory, [], :void
57
59
  attach_function :Z3_fixedpoint_add_cover, [:ctx_pointer, :fixedpoint_pointer, :int, :func_decl_pointer, :ast_pointer], :void
58
60
  attach_function :Z3_fixedpoint_add_invariant, [:ctx_pointer, :fixedpoint_pointer, :func_decl_pointer, :ast_pointer], :void
@@ -75,8 +77,6 @@ module Z3
75
77
  attach_function :Z3_fixedpoint_get_rules_along_trace, [:ctx_pointer, :fixedpoint_pointer], :ast_vector_pointer
76
78
  attach_function :Z3_fixedpoint_get_statistics, [:ctx_pointer, :fixedpoint_pointer], :stats_pointer
77
79
  attach_function :Z3_fixedpoint_inc_ref, [:ctx_pointer, :fixedpoint_pointer], :void
78
- attach_function :Z3_fixedpoint_pop, [:ctx_pointer, :fixedpoint_pointer], :void
79
- attach_function :Z3_fixedpoint_push, [:ctx_pointer, :fixedpoint_pointer], :void
80
80
  attach_function :Z3_fixedpoint_query, [:ctx_pointer, :fixedpoint_pointer, :ast_pointer], :int
81
81
  attach_function :Z3_fixedpoint_query_from_lvl, [:ctx_pointer, :fixedpoint_pointer, :ast_pointer, :uint], :int
82
82
  attach_function :Z3_fixedpoint_register_relation, [:ctx_pointer, :fixedpoint_pointer, :func_decl_pointer], :void
@@ -145,13 +145,13 @@ module Z3
145
145
  attach_function :Z3_get_full_version, [], :string
146
146
  attach_function :Z3_get_func_decl_id, [:ctx_pointer, :func_decl_pointer], :uint
147
147
  attach_function :Z3_get_index_value, [:ctx_pointer, :ast_pointer], :uint
148
- attach_function :Z3_get_interpolant, [:ctx_pointer, :ast_pointer, :ast_pointer, :params_pointer], :ast_vector_pointer
149
148
  attach_function :Z3_get_num_probes, [:ctx_pointer], :uint
150
149
  attach_function :Z3_get_num_tactics, [:ctx_pointer], :uint
150
+ attach_function :Z3_get_numeral_binary_string, [:ctx_pointer, :ast_pointer], :string
151
151
  attach_function :Z3_get_numeral_decimal_string, [:ctx_pointer, :ast_pointer, :uint], :string
152
+ attach_function :Z3_get_numeral_double, [:ctx_pointer, :ast_pointer], :double
152
153
  attach_function :Z3_get_numeral_string, [:ctx_pointer, :ast_pointer], :string
153
154
  attach_function :Z3_get_numerator, [:ctx_pointer, :ast_pointer], :ast_pointer
154
- attach_function :Z3_get_parser_error, [:ctx_pointer], :string
155
155
  attach_function :Z3_get_pattern, [:ctx_pointer, :pattern_pointer, :uint], :ast_pointer
156
156
  attach_function :Z3_get_pattern_num_terms, [:ctx_pointer, :pattern_pointer], :uint
157
157
  attach_function :Z3_get_probe_name, [:ctx_pointer, :uint], :string
@@ -165,12 +165,15 @@ module Z3
165
165
  attach_function :Z3_get_quantifier_pattern_ast, [:ctx_pointer, :ast_pointer, :uint], :pattern_pointer
166
166
  attach_function :Z3_get_quantifier_weight, [:ctx_pointer, :ast_pointer], :uint
167
167
  attach_function :Z3_get_range, [:ctx_pointer, :func_decl_pointer], :sort_pointer
168
+ attach_function :Z3_get_re_sort_basis, [:ctx_pointer, :sort_pointer], :sort_pointer
168
169
  attach_function :Z3_get_relation_arity, [:ctx_pointer, :sort_pointer], :uint
169
170
  attach_function :Z3_get_relation_column, [:ctx_pointer, :sort_pointer, :uint], :sort_pointer
171
+ attach_function :Z3_get_seq_sort_basis, [:ctx_pointer, :sort_pointer], :sort_pointer
170
172
  attach_function :Z3_get_sort, [:ctx_pointer, :ast_pointer], :sort_pointer
171
173
  attach_function :Z3_get_sort_id, [:ctx_pointer, :sort_pointer], :uint
172
174
  attach_function :Z3_get_sort_kind, [:ctx_pointer, :sort_pointer], :uint
173
175
  attach_function :Z3_get_sort_name, [:ctx_pointer, :sort_pointer], :symbol_pointer
176
+ attach_function :Z3_get_string_length, [:ctx_pointer, :ast_pointer], :uint
174
177
  attach_function :Z3_get_symbol_int, [:ctx_pointer, :symbol_pointer], :int
175
178
  attach_function :Z3_get_symbol_kind, [:ctx_pointer, :symbol_pointer], :uint
176
179
  attach_function :Z3_get_symbol_string, [:ctx_pointer, :symbol_pointer], :string
@@ -181,6 +184,7 @@ module Z3
181
184
  attach_function :Z3_global_param_reset_all, [], :void
182
185
  attach_function :Z3_global_param_set, [:string, :string], :void
183
186
  attach_function :Z3_goal_assert, [:ctx_pointer, :goal_pointer, :ast_pointer], :void
187
+ attach_function :Z3_goal_convert_model, [:ctx_pointer, :goal_pointer, :model_pointer], :model_pointer
184
188
  attach_function :Z3_goal_dec_ref, [:ctx_pointer, :goal_pointer], :void
185
189
  attach_function :Z3_goal_depth, [:ctx_pointer, :goal_pointer], :uint
186
190
  attach_function :Z3_goal_formula, [:ctx_pointer, :goal_pointer, :uint], :ast_pointer
@@ -192,18 +196,21 @@ module Z3
192
196
  attach_function :Z3_goal_precision, [:ctx_pointer, :goal_pointer], :uint
193
197
  attach_function :Z3_goal_reset, [:ctx_pointer, :goal_pointer], :void
194
198
  attach_function :Z3_goal_size, [:ctx_pointer, :goal_pointer], :uint
199
+ attach_function :Z3_goal_to_dimacs_string, [:ctx_pointer, :goal_pointer, :bool], :string
195
200
  attach_function :Z3_goal_to_string, [:ctx_pointer, :goal_pointer], :string
196
201
  attach_function :Z3_goal_translate, [:ctx_pointer, :goal_pointer, :ctx_pointer], :goal_pointer
197
202
  attach_function :Z3_inc_ref, [:ctx_pointer, :ast_pointer], :void
198
- attach_function :Z3_interpolation_profile, [:ctx_pointer], :string
199
203
  attach_function :Z3_interrupt, [:ctx_pointer], :void
200
204
  attach_function :Z3_is_algebraic_number, [:ctx_pointer, :ast_pointer], :bool
201
205
  attach_function :Z3_is_app, [:ctx_pointer, :ast_pointer], :bool
202
206
  attach_function :Z3_is_as_array, [:ctx_pointer, :ast_pointer], :bool
207
+ attach_function :Z3_is_char_sort, [:ctx_pointer, :sort_pointer], :bool
203
208
  attach_function :Z3_is_eq_ast, [:ctx_pointer, :ast_pointer, :ast_pointer], :bool
204
209
  attach_function :Z3_is_eq_func_decl, [:ctx_pointer, :func_decl_pointer, :func_decl_pointer], :bool
205
210
  attach_function :Z3_is_eq_sort, [:ctx_pointer, :sort_pointer, :sort_pointer], :bool
211
+ attach_function :Z3_is_lambda, [:ctx_pointer, :ast_pointer], :bool
206
212
  attach_function :Z3_is_numeral_ast, [:ctx_pointer, :ast_pointer], :bool
213
+ attach_function :Z3_is_quantifier_exists, [:ctx_pointer, :ast_pointer], :bool
207
214
  attach_function :Z3_is_quantifier_forall, [:ctx_pointer, :ast_pointer], :bool
208
215
  attach_function :Z3_is_well_sorted, [:ctx_pointer, :ast_pointer], :bool
209
216
  attach_function :Z3_mk_array_default, [:ctx_pointer, :ast_pointer], :ast_pointer
@@ -252,12 +259,19 @@ module Z3
252
259
  attach_function :Z3_mk_bvurem, [:ctx_pointer, :ast_pointer, :ast_pointer], :ast_pointer
253
260
  attach_function :Z3_mk_bvxnor, [:ctx_pointer, :ast_pointer, :ast_pointer], :ast_pointer
254
261
  attach_function :Z3_mk_bvxor, [:ctx_pointer, :ast_pointer, :ast_pointer], :ast_pointer
262
+ attach_function :Z3_mk_char_from_bv, [:ctx_pointer, :ast_pointer], :ast_pointer
263
+ attach_function :Z3_mk_char_is_digit, [:ctx_pointer, :ast_pointer], :ast_pointer
264
+ attach_function :Z3_mk_char_le, [:ctx_pointer, :ast_pointer, :ast_pointer], :ast_pointer
265
+ attach_function :Z3_mk_char_sort, [:ctx_pointer], :sort_pointer
266
+ attach_function :Z3_mk_char_to_bv, [:ctx_pointer, :ast_pointer], :ast_pointer
267
+ attach_function :Z3_mk_char_to_int, [:ctx_pointer, :ast_pointer], :ast_pointer
255
268
  attach_function :Z3_mk_concat, [:ctx_pointer, :ast_pointer, :ast_pointer], :ast_pointer
256
269
  attach_function :Z3_mk_config, [], :config_pointer
257
270
  attach_function :Z3_mk_const, [:ctx_pointer, :symbol_pointer, :sort_pointer], :ast_pointer
258
271
  attach_function :Z3_mk_const_array, [:ctx_pointer, :sort_pointer, :ast_pointer], :ast_pointer
259
272
  attach_function :Z3_mk_context_rc, [:config_pointer], :ctx_pointer
260
273
  attach_function :Z3_mk_div, [:ctx_pointer, :ast_pointer, :ast_pointer], :ast_pointer
274
+ attach_function :Z3_mk_divides, [:ctx_pointer, :ast_pointer, :ast_pointer], :ast_pointer
261
275
  attach_function :Z3_mk_empty_set, [:ctx_pointer, :sort_pointer], :ast_pointer
262
276
  attach_function :Z3_mk_eq, [:ctx_pointer, :ast_pointer, :ast_pointer], :ast_pointer
263
277
  attach_function :Z3_mk_ext_rotate_left, [:ctx_pointer, :ast_pointer, :ast_pointer], :ast_pointer
@@ -337,11 +351,11 @@ module Z3
337
351
  attach_function :Z3_mk_int_sort, [:ctx_pointer], :sort_pointer
338
352
  attach_function :Z3_mk_int_symbol, [:ctx_pointer, :int], :symbol_pointer
339
353
  attach_function :Z3_mk_int_to_str, [:ctx_pointer, :ast_pointer], :ast_pointer
340
- attach_function :Z3_mk_interpolant, [:ctx_pointer, :ast_pointer], :ast_pointer
341
- attach_function :Z3_mk_interpolation_context, [:config_pointer], :ctx_pointer
342
354
  attach_function :Z3_mk_is_int, [:ctx_pointer, :ast_pointer], :ast_pointer
343
355
  attach_function :Z3_mk_ite, [:ctx_pointer, :ast_pointer, :ast_pointer, :ast_pointer], :ast_pointer
344
356
  attach_function :Z3_mk_le, [:ctx_pointer, :ast_pointer, :ast_pointer], :ast_pointer
357
+ attach_function :Z3_mk_linear_order, [:ctx_pointer, :sort_pointer, :uint], :func_decl_pointer
358
+ attach_function :Z3_mk_lstring, [:ctx_pointer, :uint, :string], :ast_pointer
345
359
  attach_function :Z3_mk_lt, [:ctx_pointer, :ast_pointer, :ast_pointer], :ast_pointer
346
360
  attach_function :Z3_mk_mod, [:ctx_pointer, :ast_pointer, :ast_pointer], :ast_pointer
347
361
  attach_function :Z3_mk_model, [:ctx_pointer], :model_pointer
@@ -349,8 +363,11 @@ module Z3
349
363
  attach_function :Z3_mk_numeral, [:ctx_pointer, :string, :sort_pointer], :ast_pointer
350
364
  attach_function :Z3_mk_optimize, [:ctx_pointer], :optimize_pointer
351
365
  attach_function :Z3_mk_params, [:ctx_pointer], :params_pointer
366
+ attach_function :Z3_mk_partial_order, [:ctx_pointer, :sort_pointer, :uint], :func_decl_pointer
367
+ attach_function :Z3_mk_piecewise_linear_order, [:ctx_pointer, :sort_pointer, :uint], :func_decl_pointer
352
368
  attach_function :Z3_mk_power, [:ctx_pointer, :ast_pointer, :ast_pointer], :ast_pointer
353
369
  attach_function :Z3_mk_probe, [:ctx_pointer, :string], :probe_pointer
370
+ attach_function :Z3_mk_re_allchar, [:ctx_pointer, :sort_pointer], :ast_pointer
354
371
  attach_function :Z3_mk_re_complement, [:ctx_pointer, :ast_pointer], :ast_pointer
355
372
  attach_function :Z3_mk_re_empty, [:ctx_pointer, :sort_pointer], :ast_pointer
356
373
  attach_function :Z3_mk_re_full, [:ctx_pointer, :sort_pointer], :ast_pointer
@@ -363,11 +380,15 @@ module Z3
363
380
  attach_function :Z3_mk_repeat, [:ctx_pointer, :uint, :ast_pointer], :ast_pointer
364
381
  attach_function :Z3_mk_rotate_left, [:ctx_pointer, :uint, :ast_pointer], :ast_pointer
365
382
  attach_function :Z3_mk_rotate_right, [:ctx_pointer, :uint, :ast_pointer], :ast_pointer
383
+ attach_function :Z3_mk_sbv_to_str, [:ctx_pointer, :ast_pointer], :ast_pointer
366
384
  attach_function :Z3_mk_select, [:ctx_pointer, :ast_pointer, :ast_pointer], :ast_pointer
385
+ attach_function :Z3_mk_seq_last_index, [:ctx_pointer, :ast_pointer, :ast_pointer], :ast_pointer
386
+ attach_function :Z3_mk_seq_nth, [:ctx_pointer, :ast_pointer, :ast_pointer], :ast_pointer
367
387
  attach_function :Z3_mk_set_add, [:ctx_pointer, :ast_pointer, :ast_pointer], :ast_pointer
368
388
  attach_function :Z3_mk_set_complement, [:ctx_pointer, :ast_pointer], :ast_pointer
369
389
  attach_function :Z3_mk_set_del, [:ctx_pointer, :ast_pointer, :ast_pointer], :ast_pointer
370
390
  attach_function :Z3_mk_set_difference, [:ctx_pointer, :ast_pointer, :ast_pointer], :ast_pointer
391
+ attach_function :Z3_mk_set_has_size, [:ctx_pointer, :ast_pointer, :ast_pointer], :ast_pointer
371
392
  attach_function :Z3_mk_set_member, [:ctx_pointer, :ast_pointer, :ast_pointer], :ast_pointer
372
393
  attach_function :Z3_mk_set_sort, [:ctx_pointer, :sort_pointer], :sort_pointer
373
394
  attach_function :Z3_mk_set_subset, [:ctx_pointer, :ast_pointer, :ast_pointer], :ast_pointer
@@ -377,10 +398,15 @@ module Z3
377
398
  attach_function :Z3_mk_solver_for_logic, [:ctx_pointer, :symbol_pointer], :solver_pointer
378
399
  attach_function :Z3_mk_solver_from_tactic, [:ctx_pointer, :tactic_pointer], :solver_pointer
379
400
  attach_function :Z3_mk_store, [:ctx_pointer, :ast_pointer, :ast_pointer, :ast_pointer], :ast_pointer
401
+ attach_function :Z3_mk_str_le, [:ctx_pointer, :ast_pointer, :ast_pointer], :ast_pointer
402
+ attach_function :Z3_mk_str_lt, [:ctx_pointer, :ast_pointer, :ast_pointer], :ast_pointer
380
403
  attach_function :Z3_mk_str_to_int, [:ctx_pointer, :ast_pointer], :ast_pointer
381
404
  attach_function :Z3_mk_string_symbol, [:ctx_pointer, :string], :symbol_pointer
382
405
  attach_function :Z3_mk_tactic, [:ctx_pointer, :string], :tactic_pointer
406
+ attach_function :Z3_mk_transitive_closure, [:ctx_pointer, :func_decl_pointer], :func_decl_pointer
407
+ attach_function :Z3_mk_tree_order, [:ctx_pointer, :sort_pointer, :uint], :func_decl_pointer
383
408
  attach_function :Z3_mk_true, [:ctx_pointer], :ast_pointer
409
+ attach_function :Z3_mk_ubv_to_str, [:ctx_pointer, :ast_pointer], :ast_pointer
384
410
  attach_function :Z3_mk_unary_minus, [:ctx_pointer, :ast_pointer], :ast_pointer
385
411
  attach_function :Z3_mk_uninterpreted_sort, [:ctx_pointer, :symbol_pointer], :sort_pointer
386
412
  attach_function :Z3_mk_unsigned_int, [:ctx_pointer, :uint, :sort_pointer], :ast_pointer
@@ -401,9 +427,10 @@ module Z3
401
427
  attach_function :Z3_model_has_interp, [:ctx_pointer, :model_pointer, :func_decl_pointer], :bool
402
428
  attach_function :Z3_model_inc_ref, [:ctx_pointer, :model_pointer], :void
403
429
  attach_function :Z3_model_to_string, [:ctx_pointer, :model_pointer], :string
430
+ attach_function :Z3_model_translate, [:ctx_pointer, :model_pointer, :ctx_pointer], :model_pointer
404
431
  attach_function :Z3_optimize_assert, [:ctx_pointer, :optimize_pointer, :ast_pointer], :void
432
+ attach_function :Z3_optimize_assert_and_track, [:ctx_pointer, :optimize_pointer, :ast_pointer, :ast_pointer], :void
405
433
  attach_function :Z3_optimize_assert_soft, [:ctx_pointer, :optimize_pointer, :ast_pointer, :string, :symbol_pointer], :uint
406
- attach_function :Z3_optimize_check, [:ctx_pointer, :optimize_pointer], :int
407
434
  attach_function :Z3_optimize_dec_ref, [:ctx_pointer, :optimize_pointer], :void
408
435
  attach_function :Z3_optimize_from_file, [:ctx_pointer, :optimize_pointer, :string], :void
409
436
  attach_function :Z3_optimize_from_string, [:ctx_pointer, :optimize_pointer, :string], :void
@@ -416,6 +443,7 @@ module Z3
416
443
  attach_function :Z3_optimize_get_param_descrs, [:ctx_pointer, :optimize_pointer], :param_descrs_pointer
417
444
  attach_function :Z3_optimize_get_reason_unknown, [:ctx_pointer, :optimize_pointer], :string
418
445
  attach_function :Z3_optimize_get_statistics, [:ctx_pointer, :optimize_pointer], :stats_pointer
446
+ attach_function :Z3_optimize_get_unsat_core, [:ctx_pointer, :optimize_pointer], :ast_vector_pointer
419
447
  attach_function :Z3_optimize_get_upper, [:ctx_pointer, :optimize_pointer, :uint], :ast_pointer
420
448
  attach_function :Z3_optimize_get_upper_as_vector, [:ctx_pointer, :optimize_pointer, :uint], :ast_vector_pointer
421
449
  attach_function :Z3_optimize_inc_ref, [:ctx_pointer, :optimize_pointer], :void
@@ -485,6 +513,7 @@ module Z3
485
513
  attach_function :Z3_solver_assert, [:ctx_pointer, :solver_pointer, :ast_pointer], :void
486
514
  attach_function :Z3_solver_assert_and_track, [:ctx_pointer, :solver_pointer, :ast_pointer, :ast_pointer], :void
487
515
  attach_function :Z3_solver_check, [:ctx_pointer, :solver_pointer], :int
516
+ attach_function :Z3_solver_cube, [:ctx_pointer, :solver_pointer, :ast_vector_pointer, :uint], :ast_vector_pointer
488
517
  attach_function :Z3_solver_dec_ref, [:ctx_pointer, :solver_pointer], :void
489
518
  attach_function :Z3_solver_from_file, [:ctx_pointer, :solver_pointer, :string], :void
490
519
  attach_function :Z3_solver_from_string, [:ctx_pointer, :solver_pointer, :string], :void
@@ -492,17 +521,24 @@ module Z3
492
521
  attach_function :Z3_solver_get_consequences, [:ctx_pointer, :solver_pointer, :ast_vector_pointer, :ast_vector_pointer, :ast_vector_pointer], :int
493
522
  attach_function :Z3_solver_get_help, [:ctx_pointer, :solver_pointer], :string
494
523
  attach_function :Z3_solver_get_model, [:ctx_pointer, :solver_pointer], :model_pointer
524
+ attach_function :Z3_solver_get_non_units, [:ctx_pointer, :solver_pointer], :ast_vector_pointer
495
525
  attach_function :Z3_solver_get_num_scopes, [:ctx_pointer, :solver_pointer], :uint
496
526
  attach_function :Z3_solver_get_param_descrs, [:ctx_pointer, :solver_pointer], :param_descrs_pointer
497
527
  attach_function :Z3_solver_get_proof, [:ctx_pointer, :solver_pointer], :ast_pointer
498
528
  attach_function :Z3_solver_get_reason_unknown, [:ctx_pointer, :solver_pointer], :string
499
529
  attach_function :Z3_solver_get_statistics, [:ctx_pointer, :solver_pointer], :stats_pointer
530
+ attach_function :Z3_solver_get_trail, [:ctx_pointer, :solver_pointer], :ast_vector_pointer
531
+ attach_function :Z3_solver_get_units, [:ctx_pointer, :solver_pointer], :ast_vector_pointer
500
532
  attach_function :Z3_solver_get_unsat_core, [:ctx_pointer, :solver_pointer], :ast_vector_pointer
533
+ attach_function :Z3_solver_import_model_converter, [:ctx_pointer, :solver_pointer, :solver_pointer], :void
501
534
  attach_function :Z3_solver_inc_ref, [:ctx_pointer, :solver_pointer], :void
535
+ attach_function :Z3_solver_interrupt, [:ctx_pointer, :solver_pointer], :void
502
536
  attach_function :Z3_solver_pop, [:ctx_pointer, :solver_pointer, :uint], :void
537
+ attach_function :Z3_solver_propagate_register, [:ctx_pointer, :solver_pointer, :ast_pointer], :uint
503
538
  attach_function :Z3_solver_push, [:ctx_pointer, :solver_pointer], :void
504
539
  attach_function :Z3_solver_reset, [:ctx_pointer, :solver_pointer], :void
505
540
  attach_function :Z3_solver_set_params, [:ctx_pointer, :solver_pointer, :params_pointer], :void
541
+ attach_function :Z3_solver_to_dimacs_string, [:ctx_pointer, :solver_pointer, :bool], :string
506
542
  attach_function :Z3_solver_to_string, [:ctx_pointer, :solver_pointer], :string
507
543
  attach_function :Z3_stats_dec_ref, [:ctx_pointer, :stats_pointer], :void
508
544
  attach_function :Z3_stats_get_double_value, [:ctx_pointer, :stats_pointer, :uint], :double
@@ -4,6 +4,7 @@ module Z3
4
4
  let(:b) { Z3.Bitvec("b", 8) }
5
5
  let(:c) { Z3.Bitvec("c", 8) }
6
6
  let(:d) { Z3.Bitvec("d", 12) }
7
+ let(:e) { Z3.Bitvec("e", 4) }
7
8
  let(:x) { Z3.Bool("x") }
8
9
 
9
10
  it "==" do
@@ -168,28 +169,28 @@ module Z3
168
169
  expect([a == 127, b == 1, x == a.signed_div_no_overflow?(b)]).to have_solution(x => true)
169
170
  end
170
171
 
171
- ## This API is broken, z3 returns unevaluated bvsmul_noovfl(10, 10) instead of actual answer
172
-
173
- # it "signed_mul_no_overflow?" do
174
- # expect([a == 10, b == 10, x == a.signed_mul_no_overflow?(b)]).to have_solution(x => true)
175
- # expect([a == 20, b == 10, x == a.signed_mul_no_overflow?(b)]).to have_solution(x => false)
176
- # expect([a == 20, b == 20, x == a.signed_mul_no_overflow?(b)]).to have_solution(x => false)
177
- # expect([a == -10, b == -10, x == a.signed_mul_no_overflow?(b)]).to have_solution(x => true)
178
- # end
179
- #
180
- # it "unsigned_mul_no_overflow?" do
181
- # expect([a == 10, b == 10, x == a.unsigned_mul_no_overflow?(b)]).to have_solution(x => true)
182
- # expect([a == 20, b == 10, x == a.unsigned_mul_no_overflow?(b)]).to have_solution(x => true)
183
- # expect([a == 20, b == 20, x == a.unsigned_mul_no_overflow?(b)]).to have_solution(x => false)
184
- # expect([a == -10, b == -10, x == a.unsigned_mul_no_overflow?(b)]).to have_solution(x => false)
185
- # end
186
- #
172
+ it "signed_mul_no_overflow?" do
173
+ expect([a == 10, b == 10, x == a.signed_mul_no_overflow?(b)]).to have_solution(x => true)
174
+ expect([a == 20, b == 10, x == a.signed_mul_no_overflow?(b)]).to have_solution(x => false)
175
+ expect([a == 20, b == 20, x == a.signed_mul_no_overflow?(b)]).to have_solution(x => false)
176
+ expect([a == 10, b == -10, x == a.signed_mul_no_overflow?(b)]).to have_solution(x => false)
177
+ expect([a == -10, b == 10, x == a.signed_mul_no_overflow?(b)]).to have_solution(x => false)
178
+ expect([a == -10, b == -10, x == a.signed_mul_no_overflow?(b)]).to have_solution(x => false)
179
+ end
180
+
181
+ it "unsigned_mul_no_overflow?" do
182
+ expect([a == 10, b == 10, x == a.unsigned_mul_no_overflow?(b)]).to have_solution(x => true)
183
+ expect([a == 20, b == 10, x == a.unsigned_mul_no_overflow?(b)]).to have_solution(x => true)
184
+ expect([a == 20, b == 20, x == a.unsigned_mul_no_overflow?(b)]).to have_solution(x => false)
185
+ expect([a == -10, b == -10, x == a.unsigned_mul_no_overflow?(b)]).to have_solution(x => false)
186
+ end
187
+
187
188
  # # Inherently signed, unsigned can't underflow
188
- # it "signed_mul_no_underflow?" do
189
- # expect([a == -10, b == -10, x == a.signed_mul_no_underflow?(b)]).to have_solution(x => true)
190
- # expect([a == -20, b == -20, x == a.signed_mul_no_underflow?(b)]).to have_solution(x => true)
191
- # expect([a == -20, b == 20, x == a.signed_mul_no_underflow?(b)]).to have_solution(x => false)
192
- # end
189
+ it "signed_mul_no_underflow?" do
190
+ expect([a == -10, b == -10, x == a.signed_mul_no_underflow?(b)]).to have_solution(x => true)
191
+ expect([a == -20, b == -20, x == a.signed_mul_no_underflow?(b)]).to have_solution(x => true)
192
+ expect([a == -20, b == 20, x == a.signed_mul_no_underflow?(b)]).to have_solution(x => false)
193
+ end
193
194
 
194
195
  it "zero_ext / sign_ext" do
195
196
  expect([a == 100, d == a.zero_ext(4)]).to have_solution(d => 100)
@@ -204,5 +205,18 @@ module Z3
204
205
  expect([a == 0b0101_0110, b == a.rotate_right(1)]).to have_solution(b => 0b0_0101_011)
205
206
  expect([a == 0b0101_0110, b == a.rotate_right(4)]).to have_solution(b => 0b0110_0101)
206
207
  end
208
+
209
+ it "extract" do
210
+ expect([a == 0b0101_0110, e == a.extract(3, 0)]).to have_solution(e => 0b0110)
211
+ expect([a == 0b0101_0110, e == a.extract(7, 4)]).to have_solution(e => 0b0101)
212
+ expect{ a.extract(8, 4) }.to raise_error(Z3::Exception)
213
+ expect{ a.extract(2, 3) }.to raise_error(Z3::Exception)
214
+ expect{ a.extract(2, -1) }.to raise_error(Z3::Exception)
215
+ end
216
+
217
+ it "concat" do
218
+ expect([a == 0b0101_0110, e == 0b1101, d == a.concat(e)]).to have_solution(d => 0b0101_0110_1101)
219
+ expect([a == 0b0101_0110, e == 0b1101, d == e.concat(a)]).to have_solution(d => 0b1101_0101_0110)
220
+ end
207
221
  end
208
222
  end
@@ -32,5 +32,9 @@ module Z3
32
32
  expect(Z3.Bitvec("a", 8).inspect).to eq("Bitvec(8)<a>")
33
33
  expect(Z3.Bitvec("a", 32).inspect).to eq("Bitvec(32)<a>")
34
34
  end
35
+
36
+ it "number of bits must be positive" do
37
+ expect{ Z3.Bitvec("a", 0) }.to raise_error(Z3::Exception)
38
+ end
35
39
  end
36
40
  end
data/spec/expr_spec.rb CHANGED
@@ -183,4 +183,66 @@ module Z3
183
183
  end
184
184
  end
185
185
  end
186
+
187
+ describe "#hash / #eql?" do
188
+ let(:x1) { Z3.Int("x") }
189
+ let(:x2) { Z3.Int("x") }
190
+ let(:y1) { Z3.Int("y") }
191
+ let(:y2) { Z3.Int("y") }
192
+ let(:e1) { x1 + y1 }
193
+ let(:e2) { x2 + y2 }
194
+ let(:f1) { y1 + x1 }
195
+ let(:f2) { y2 + x2 }
196
+ let(:samples) { [x1, x2, y1, y2, e1, e2, f1, f2] }
197
+
198
+ it "object is eql? to itself" do
199
+ expect(x1.eql?(x1)).to be true
200
+ expect(y1.eql?(y1)).to be true
201
+ expect(e1.eql?(e1)).to be true
202
+
203
+ expect(x1.eql?(y1)).to be false
204
+ expect(x1.eql?(e1)).to be false
205
+ end
206
+
207
+ it "object is eql? to structurally identical object" do
208
+ expect(x1.eql?(x2)).to be true
209
+ expect(y1.eql?(y2)).to be true
210
+ expect(e1.eql?(e2)).to be true
211
+ expect(f1.eql?(f2)).to be true
212
+ end
213
+
214
+ it "object is not eql? to semantically identical object" do
215
+ expect(e1.eql?(f1)).to be false
216
+ end
217
+
218
+ it "#hash aligns with #eql?" do
219
+ samples.each do |a|
220
+ samples.each do |b|
221
+ if a.eql?(b)
222
+ expect(a.hash).to eq(b.hash)
223
+ else
224
+ expect(a.hash).to_not eq(b.hash)
225
+ end
226
+ end
227
+ end
228
+ end
229
+
230
+ it "works when used as Hash keys" do
231
+ ht = {}
232
+ ht[x1] = 1
233
+ ht[y1] = 2
234
+ ht[e1] = 3
235
+ ht[e2] = 4
236
+
237
+ expect(ht.size).to eq(3)
238
+ expect(ht[x1]).to eq(1)
239
+ expect(ht[x2]).to eq(1)
240
+ expect(ht[y1]).to eq(2)
241
+ expect(ht[y2]).to eq(2)
242
+ expect(ht[e1]).to eq(4)
243
+ expect(ht[e2]).to eq(4)
244
+ expect(ht[f1]).to eq(nil)
245
+ expect(ht[f2]).to eq(nil)
246
+ end
247
+ end
186
248
  end
@@ -0,0 +1,21 @@
1
+ # There are multiple solutions, so this test is nondeterministic
2
+ # This is what Z3 4.8.13 returns
3
+ describe "ABC Path" do
4
+ it do
5
+ expect("abc_path").to have_output <<'EOF'
6
+ C O R D F B U
7
+
8
+ N o-n l-k-j L
9
+ | |/ |
10
+ G p m g-f i I
11
+ | x /
12
+ Q q-r e h a H
13
+ / | |
14
+ V s v d-c-b S
15
+ x \
16
+ T u-t w-x-y X
17
+
18
+ J P M W K Y E
19
+ EOF
20
+ end
21
+ end
@@ -0,0 +1,27 @@
1
+ describe "Aquarium" do
2
+ it do
3
+ expect("aquarium").to have_output <<EOF
4
+ +-+-+-+-+-+-+-+-+-+-+
5
+ |# #|# # # # #|# #| |
6
+ + +-+-+-+-+-+ +-+ + +
7
+ |#|#| |# #|#|#|
8
+ + + + +-+-+-+-+-+-+-+
9
+ |#|#| |# #|# #| |#|
10
+ + + + +-+-+-+-+ + +
11
+ |#|#|#| | | |#|
12
+ + +-+-+ + +-+-+-+
13
+ |#| | | |
14
+ + + +-+ +-+ + +-+-+
15
+ |#| | | | |#|#|# #|
16
+ + + + +-+-+ + +-+ +
17
+ |#| | | |#| |# #|
18
+ + + +-+ + +-+ +-+ +
19
+ |#|# #| | |# # #|#|
20
+ +-+-+-+ + + +-+-+-+
21
+ | | |#|#|#| |
22
+ + +-+-+ + +-+ + +
23
+ |# # #| |# #|#|# #|
24
+ +-+-+-+-+-+-+-+-+-+-+
25
+ EOF
26
+ end
27
+ end
@@ -0,0 +1,14 @@
1
+ describe "Cats Organized Neatly" do
2
+ it do
3
+ expect("cats_organized_neatly").to have_output <<EOF
4
+ .ffffbbb
5
+ .fdddbbb
6
+ aadddbbb
7
+ aadddbbe
8
+ aagggcee
9
+ aagggcce
10
+ aagggcc.
11
+ ..gggcc.
12
+ EOF
13
+ end
14
+ end
@@ -0,0 +1,28 @@
1
+ describe "Color Nonogram" do
2
+ let(:ascii_board) do <<EOF
3
+ 3 3 3 3 3 3 3 3 3 3
4
+ 3 0 2 2 0 0 0 0 0 3
5
+ 3 0 0 0 0 0 0 0 0 3
6
+ 3 2 1 0 0 0 2 1 0 3
7
+ 3 3 3 0 0 0 1 1 0 0
8
+ 3 0 0 0 0 0 0 0 0 0
9
+ 0 2 2 1 2 2 2 2 0 3
10
+ 0 0 2 2 2 2 2 0 0 3
11
+ 3 0 0 0 0 0 0 0 0 3
12
+ 3 0 0 3 3 3 3 0 0 3
13
+ EOF
14
+ end
15
+
16
+ it do
17
+ color_board = ascii_board.gsub(/\d/) do |i|
18
+ {
19
+ "0" => "\e[38;2;255;0;0m0\e[0m",
20
+ "1" => "\e[38;2;0;0;0m1\e[0m",
21
+ "2" => "\e[38;2;255;255;255m2\e[0m",
22
+ "3" => "\e[38;2;165;42;42m3\e[0m",
23
+ }[i]
24
+ end
25
+
26
+ expect("color_nonogram").to have_output color_board
27
+ end
28
+ end
@@ -0,0 +1,14 @@
1
+ describe "Dominion" do
2
+ it do
3
+ expect("dominion").to have_output <<EOF
4
+ **AAAA*B
5
+ FF*AAA*B
6
+ FF*A**BB
7
+ F*E*GG**
8
+ F*E*G*DD
9
+ *G*GG*DD
10
+ *G*G*C**
11
+ GGGG*CCC
12
+ EOF
13
+ end
14
+ end
@@ -0,0 +1,21 @@
1
+ describe "Dominosa" do
2
+ it do
3
+ expect("dominosa").to have_output <<EOF
4
+ 5*5 7 4*1 1 4 2 3
5
+ * * * * *
6
+ 2*0 2 4*7 5 4 2 0
7
+
8
+ 4*0 0 3 2 0 3 4*5
9
+ * * * * *
10
+ 1*1 6 4 6 5 2 5 6
11
+ * *
12
+ 6 1 1 7*7 5 6 3 6
13
+ * * * * *
14
+ 7 3 0 2*4 2 1 6*3
15
+
16
+ 6 5*6 0 1 3*3 0*0
17
+ * * *
18
+ 4 5*7 7 7 2*1 7*3
19
+ EOF
20
+ end
21
+ end
@@ -0,0 +1,11 @@
1
+ describe "Eulero" do
2
+ it do
3
+ expect("eulero").to have_output <<EOF
4
+ C2 B4 D5 A1 E3
5
+ D1 A2 B3 E5 C4
6
+ E4 D3 C1 B2 A5
7
+ B5 E1 A4 C3 D2
8
+ A3 C5 E2 D4 B1
9
+ EOF
10
+ end
11
+ end
@@ -0,0 +1,23 @@
1
+ describe "Futoshiki" do
2
+ it do
3
+ expect("futoshiki").to have_output <<EOF
4
+ 2 5 3 4 1 7 6<9 8
5
+
6
+ 1 9 7 2 8 5 3<4<6
7
+ _
8
+ 7<8 2 5>3>1 4<6 9
9
+ ^
10
+ 8 1<5<9 7 6 2 3 4
11
+ ^
12
+ 4 7>6>1 9 2 5 8 3
13
+ ^ ^ ^
14
+ 6 4 1 8 2 3 9 5 7
15
+ _ _ ^ _ _
16
+ 9 3 4 6>5 8 7 1 2
17
+ _
18
+ 5 2 9>3 6>4 8>7 1
19
+ _
20
+ 3 6 8>7>4 9 1<2 5
21
+ EOF
22
+ end
23
+ end
@@ -0,0 +1,18 @@
1
+ describe "Kakurasu" do
2
+ it do
3
+ expect("kakurasu").to have_output <<EOF
4
+ [ ][ ][X][ ][ ][ ][X][ ][ ][ ][ ][ ]
5
+ [ ][X][ ][X][ ][ ][ ][ ][ ][X][X][X]
6
+ [ ][X][X][X][ ][ ][X][ ][ ][ ][ ][ ]
7
+ [ ][X][X][ ][ ][X][X][X][X][ ][X][X]
8
+ [ ][X][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
9
+ [ ][ ][X][ ][ ][ ][ ][X][ ][ ][X][ ]
10
+ [X][ ][ ][ ][ ][X][X][ ][ ][ ][X][X]
11
+ [ ][ ][ ][ ][ ][ ][X][ ][ ][ ][X][X]
12
+ [ ][ ][X][ ][ ][ ][ ][ ][ ][ ][X][ ]
13
+ [ ][ ][ ][ ][X][ ][X][ ][X][ ][X][ ]
14
+ [ ][ ][ ][ ][ ][X][X][ ][X][ ][X][ ]
15
+ [ ][ ][X][ ][X][ ][X][ ][X][ ][X][ ]
16
+ EOF
17
+ end
18
+ end
@@ -0,0 +1,10 @@
1
+ describe "Killer Sudoku" do
2
+ it do
3
+ expect("killer_sudoku").to have_output <<EOF
4
+ 4 2 3 1
5
+ 3 1 2 4
6
+ 2 4 1 3
7
+ 1 3 4 2
8
+ EOF
9
+ end
10
+ end