z3 0.0.20180624 → 0.0.20211213

Sign up to get free protection for your applications and to get access to all the features.
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