mbt-gen 0.0.13 → 0.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 112610c6e247d3de6fc7c69afc0a668659dbcffc9ee1786967bf4a69d9586520
4
- data.tar.gz: d0eea35ebf9689ca1bead1e9efe8e8f2a96b75d45b644484875e383927dd2b91
3
+ metadata.gz: 4dab888f896a820078b818a69beb6c96832509be151437332a64efe493c99c43
4
+ data.tar.gz: 7bb0d5281265df6171e316c4c5cf5b2f6ef909bee7549cb6213c3d61e79c46fe
5
5
  SHA512:
6
- metadata.gz: 137856eff73bfde902b67a9bdc97426253b036a79be6d1b6e912ceaa6012a27bb27715d3de26fb75210602985b8e8bdbe6e43cf15db8edb4f931db69f9b16c5d
7
- data.tar.gz: 37e9195a691a211aca006aef7ba57cfc5a91d46f61327acd0297385911f8d29fe4b60dcd77a3514a3b5565aff7d5517d92413e3a80005eff1b24c204bd83c87e
6
+ metadata.gz: e14470e1741ccc1dfede14112f045bb952f42afbb4c8d55af8ac42bcf4517ae4de9fe0fedd6b3296c3a51651665c8d2d3a996e51fa7be892e7a9dea6890d28c7
7
+ data.tar.gz: 6e723168766e1dc4414e9e25344e9a3f2abc4b6704e5d25bb85e19c20b9f933b37deea1fa904f2954689151a4db3b41a6c427856ce5534e10473540a43ed6fd4
data/lib/mbt-gen.rb CHANGED
@@ -182,6 +182,10 @@ def maxLength_contraint_for_expr(expr, maxLength)
182
182
  "(<= (str.len #{expr}) #{maxLength})"
183
183
  end
184
184
 
185
+ def minLength_contraint_for_expr(expr, minLength)
186
+ "(>= (str.len #{expr}) #{minLength})"
187
+ end
188
+
185
189
  def oneOf_contraint_for_expr(expr, values)
186
190
  list = values.map do |val|
187
191
  "(= #{expr} \"#{val}\")"
@@ -246,7 +250,6 @@ def translate_field_def_to_SMTLIB_constraints(progress, solver, fielddef, xpath,
246
250
  solver.associateAssertionIDWith(assertionID, info)
247
251
  solver.to_solver(progress, "(assert (! (=> #{varname}-filled #{regex_constraint_for_expr("#{varname}-value", fielddef[:regex])}) :named #{assertionID}))")
248
252
  end
249
- # TODO: minLength?
250
253
  if fielddef[:maxLength] then
251
254
  assertionID = "maxLength-#{varname}"
252
255
  info = {
@@ -259,6 +262,18 @@ def translate_field_def_to_SMTLIB_constraints(progress, solver, fielddef, xpath,
259
262
  solver.associateAssertionIDWith(assertionID, info)
260
263
  solver.to_solver(progress, "(assert (! (=> #{varname}-filled #{maxLength_contraint_for_expr("#{varname}-value", fielddef[:maxLength])}) :named #{assertionID}))")
261
264
  end
265
+ if fielddef[:minLength] then
266
+ assertionID = "minLength-#{varname}"
267
+ info = {
268
+ :assertion_type => :constraint,
269
+ :xpath => xpath,
270
+ :datatype => :string,
271
+ :value => fielddef[:minLength],
272
+ :constraint_type => :minLength
273
+ }
274
+ solver.associateAssertionIDWith(assertionID, info)
275
+ solver.to_solver(progress, "(assert (! (=> #{varname}-filled #{minLength_contraint_for_expr("#{varname}-value", fielddef[:minLength])}) :named #{assertionID}))")
276
+ end
262
277
  if fielddef[:from_list] then
263
278
  assertionID = "oneOf-#{varname}"
264
279
  list_filename = "#{LISTS_DIR}/#{fielddef[:from_list]}"
@@ -310,12 +325,16 @@ def translate_list_def_to_SMTLIB_constraints(progress, solver, fielddef, varname
310
325
  solver.to_solver(progress, "(assert (! (=> (< #{i} #{varname}-size) #{regex_constraint_for_expr("#{varname}-index-#{i}-value", fielddef[:regex])}) :named list-regex-#{varname}-index-#{i}))")
311
326
  end
312
327
  end
313
- # TODO: minLength?
314
328
  if fielddef[:maxLength] then
315
329
  fielddef[:model_maxLength].times do |i|
316
330
  solver.to_solver(progress, "(assert (! (=> (< #{i} #{varname}-size) #{maxLength_contraint_for_expr("#{varname}-index-#{i}-value", fielddef[:maxLength])}) :named list-maxLength-#{varname}-index-#{i}))")
317
331
  end
318
332
  end
333
+ if fielddef[:minLength] then
334
+ fielddef[:model_maxLength].times do |i|
335
+ solver.to_solver(progress, "(assert (! (=> (< #{i} #{varname}-size) #{minLength_contraint_for_expr("#{varname}-index-#{i}-value", fielddef[:minLength])}) :named list-minLength-#{varname}-index-#{i}))")
336
+ end
337
+ end
319
338
  when :enum
320
339
  fielddef[:model_maxLength].times do |i|
321
340
  solver.to_solver(progress, "(assert (! (=> (< #{i} #{varname}-size) #{enum_constraint_for_expr("#{varname}-index-#{i}-value", fielddef[:values])}) :named list-enum-#{varname}-index-#{i}))")
@@ -412,7 +431,7 @@ def translate_substructure_to_SMTLIB(progress, solver, struct, hash = {})
412
431
  solver.to_solver(progress, "(assert (! (=> (not #{filled_var_for_field(xpath)}) (= #{size_var_for_list(xpath)} 0)) :named empty-objlist-has-zero-size-#{raw_field(xpath)}))")
413
432
  solver.to_solver(progress, "(assert (! (=> (= #{size_var_for_list(xpath)} 0) (not #{filled_var_for_field(xpath)})) :named objlist-has-zero-size-implies-empty-objlist-#{raw_field(xpath)}))")
414
433
  minSize = 0
415
- solver.to_solver(progress, "(assert (! (=> #{filled_var_for_field(xpath)} (and (> #{size_var_for_list(xpath)} #{minSize}) (< #{size_var_for_list(xpath)} #{definition[:model_maxLength]}))) :named filled-objlist-has-positive-size-#{raw_field(xpath)}))")
434
+ solver.to_solver(progress, "(assert (! (=> #{filled_var_for_field(xpath)} (and (> #{size_var_for_list(xpath)} #{minSize}) (<= #{size_var_for_list(xpath)} #{definition[:model_maxLength]}))) :named filled-objlist-has-positive-size-#{raw_field(xpath)}))")
416
435
  solver.to_solver(progress, "(assert (! (=> (> #{size_var_for_list(xpath)} 0) #{filled_var_for_field(xpath)}) :named objlist-has-positive-size-implies-filled-objlist-#{raw_field(xpath)}))")
417
436
  definition[:model_maxLength].times do |i|
418
437
  ext_xpath = "#{xpath}/#{i}"
@@ -628,7 +647,7 @@ def translate_validation_rule_to_SMTLIB(rule, context_struct, prefix, config, op
628
647
  raise RuntimeError.new("could not parse LIST_VALUE_FIRST_ELEMENT[...]: #{m.inspect} in validation rule #{rule_name}")
629
648
  end
630
649
  xpath = $1
631
- index = Integer($2)
650
+ index = Integer($2, 10)
632
651
  l = resolve_field_path(xpath, context_struct, prefix)
633
652
  value_var_for_list(l, index)
634
653
  end
@@ -724,7 +743,7 @@ def translate_validation_rule_to_SMTLIB(rule, context_struct, prefix, config, op
724
743
  end
725
744
  elsif fdef[:datatype] == :int then
726
745
  terms = values.filter{|l| !l.start_with?("#")}.map do |val|
727
- "(= #{value_var_for_field(fpath)} #{Integer(val)})"
746
+ "(= #{value_var_for_field(fpath)} #{Integer(val, 10)})"
728
747
  end
729
748
  else
730
749
  raise RuntimeError.new("FIELD_IN_QUERY[] was applied to a field of datatype #{fdef[:datatype].inspect}. However, it can only be applied to fields of datatype string or int.")
@@ -793,7 +812,7 @@ def parse_field_value(fielddef, value)
793
812
  datatype = fielddef[:datatype]
794
813
  case datatype
795
814
  when :int
796
- return Integer(value)
815
+ return Integer(value, 10)
797
816
  when :string
798
817
  return solver_value_to_string(value)
799
818
  when :enum
@@ -847,7 +866,11 @@ def pick_solver_value_for_field(field_desc)
847
866
  if field_desc[:maxLength] then
848
867
  "a" * field_desc[:maxLength]
849
868
  else
850
- "default"
869
+ if field_desc[:minLength] then
870
+ "a" * field_desc[:minLength]
871
+ else
872
+ "default"
873
+ end
851
874
  end
852
875
  elsif field_desc[:datatype] == :enum then
853
876
  field_desc[:values].first.to_s
@@ -878,8 +901,8 @@ def add_max_struct_to_doc(progress, struct, doc, prefix = nil)
878
901
  node = node.first
879
902
  end
880
903
  xpath_element = value[:xpath_element]
881
- if Integer(value[:model_maxLength]) > 0 then
882
- Integer(value[:model_maxLength]).times do |i|
904
+ if Integer(value[:model_maxLength], 10) > 0 then
905
+ Integer(value[:model_maxLength], 10).times do |i|
883
906
  node.add_child("<#{xpath_element}>#{format_solver_value(value, pick_solver_value_for_field(value))}</#{xpath_element}>")
884
907
  end
885
908
  end
@@ -941,8 +964,8 @@ def add_model_struct_to_doc(progress, struct, doc, model, prefix = nil)
941
964
  node = node.first
942
965
  end
943
966
  xpath_element = value[:xpath_element]
944
- if Integer(model_value[:size]) > 0 then
945
- model_value[:value].slice(0, Integer(model_value[:size])).each do |mvalue|
967
+ if Integer(model_value[:size], 10) > 0 then
968
+ model_value[:value].slice(0, Integer(model_value[:size], 10)).each do |mvalue|
946
969
  node.add_child("<#{xpath_element}>#{solver_value_to_string(mvalue)}</#{xpath_element}>")
947
970
  end
948
971
  end
@@ -952,7 +975,7 @@ def add_model_struct_to_doc(progress, struct, doc, model, prefix = nil)
952
975
  node = node.first
953
976
  end
954
977
  xpath_element = value[:xpath_element]
955
- if Integer(model_value[:size]) > 0 then
978
+ if Integer(model_value[:size], 10) > 0 then
956
979
  model_value[:size].times do |index|
957
980
  cnode = node.add_child("<#{xpath_element}></#{xpath_element}>")
958
981
  if cnode.is_a?(Nokogiri::XML::NodeSet) then
@@ -1328,7 +1351,7 @@ def z3ValueToRubyValue(value)
1328
1351
  if value =~ /\"(.*)\"/ then # string
1329
1352
  return $1
1330
1353
  elsif value =~ /\d+/ then # int
1331
- return Integer(value)
1354
+ return Integer(value, 10)
1332
1355
  elsif value == "true"
1333
1356
  return true
1334
1357
  elsif value == "false" then
@@ -1596,7 +1619,7 @@ def default_parser_for_type(value_str, datatype)
1596
1619
  if datatype == :string or datatype == :enum then
1597
1620
  value_str
1598
1621
  elsif datatype == :int then
1599
- Integer(value_str)
1622
+ Integer(value_str, 10)
1600
1623
  elsif datatype == :date then
1601
1624
  Date.parse(value_str)
1602
1625
  elsif datatype == :timestamp then
@@ -1819,12 +1842,12 @@ class CoreEnumerationAlgo
1819
1842
 
1820
1843
  def self.parse_continuation_point(line)
1821
1844
  split = line.split(";")
1822
- doc_number = Integer(split[0])
1823
- num_docs = Integer(split[1])
1845
+ doc_number = Integer(split[0], 10)
1846
+ num_docs = Integer(split[1], 10)
1824
1847
  state = CoreEnumerationAlgo.parse_state(split[2])
1825
1848
  assignment = CoreEnumerationAlgo.parse_assignment(split[3])
1826
1849
  new_assignment = CoreEnumerationAlgo.parse_assignment(split[4])
1827
- processessing_time = Integer(split[5])
1850
+ processessing_time = Integer(split[5], 10)
1828
1851
  return [doc_number, num_docs, state, assignment, new_assignment, processessing_time]
1829
1852
  end
1830
1853
 
@@ -2523,7 +2546,7 @@ def generate(message, argv, message_config_filename = nil)
2523
2546
  elsif opt == "-generate-docs-from" then
2524
2547
  options[:combination_source] = argv.shift
2525
2548
  elsif opt == "-skip" then
2526
- options[:skip] = Integer(argv.shift)
2549
+ options[:skip] = Integer(argv.shift, 10)
2527
2550
  elsif opt == "-generate-docs-for-key" then
2528
2551
  options[:docs_for_key] = argv.shift
2529
2552
  elsif opt == "-count-docs-for-key" then
@@ -2531,7 +2554,7 @@ def generate(message, argv, message_config_filename = nil)
2531
2554
  elsif opt == "-continue" then
2532
2555
  options[:continue] = true
2533
2556
  elsif opt == "-max-num-docs" then
2534
- options[:max_num_docs] = Integer(argv.shift)
2557
+ options[:max_num_docs] = Integer(argv.shift, 10)
2535
2558
  puts "flag -max-num-docs used. Will stop after generating #{options[:max_num_docs]} documents."
2536
2559
  elsif opt == "-validate" then
2537
2560
  if options.has_key?(:validate_files) then
@@ -84,8 +84,8 @@ class Regexp_to_SMTLIB
84
84
  return "(re.opt #{expr})"
85
85
  elsif multiplicator =~ /\{(\d+),(\d+)\}/ then
86
86
  begin
87
- lower = Integer($1)
88
- upper = Integer($2)
87
+ lower = Integer($1, 10)
88
+ upper = Integer($2, 10)
89
89
  rescue TypeError => e
90
90
  raise RuntimeError.new("cannot parse regexp (#{$1} or #{$2} is no Integer)")
91
91
  end
@@ -117,4 +117,4 @@ class Regexp_to_SMTLIB
117
117
  end
118
118
 
119
119
 
120
- end
120
+ end
data/lib/solver-lib.rb CHANGED
@@ -337,7 +337,7 @@ class SolverFactory
337
337
  unless varname =~ /-index-(\d+)-value$/
338
338
  raise RuntimeError.new("inconsistent model: xpath #{xpath} is a list value and hence its varname should end like -index-X-value, not #{varname.inspect}.")
339
339
  end
340
- index = Integer($1)
340
+ index = Integer($1, 10)
341
341
  model[xpath][:xpath_element] = info[:xpath_element]
342
342
  if model[xpath].has_key?(:value) then
343
343
  val = convert_solver_value(info[:type], info[:datatype], value, xpath)
@@ -354,7 +354,7 @@ class SolverFactory
354
354
  if model[xpath][:type] == :field then
355
355
  model[xpath][:type] = :list
356
356
  end
357
- model[xpath][:size] = Integer(value)
357
+ model[xpath][:size] = Integer(value, 10)
358
358
  elsif varname.start_with?("struct-") && varname.end_with?("-exists") then
359
359
  unless model[xpath][:type] == :struct then
360
360
  raise RuntimeError.new("inconsistent model: xpath #{xpath} should be a struct, not a #{model[xpath][:type]}.")
@@ -403,9 +403,9 @@ class SolverFactory
403
403
  def convert_solver_value(type, datatype, value, xpath)
404
404
  check_type(type, value, xpath)
405
405
  if datatype == :date then
406
- return (Time.at(0).to_date + Integer(value)).to_s
406
+ return (Time.at(0).to_date + Integer(value, 10)).to_s
407
407
  elsif datatype == :timestamp then
408
- return Time.at(Integer(value)).to_s
408
+ return Time.at(Integer(value, 10)).to_s
409
409
  else
410
410
  return value
411
411
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mbt-gen
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.13
4
+ version: 0.0.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - FM-enthusiast
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-11-01 00:00:00.000000000 Z
11
+ date: 2026-11-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri