mbt-gen 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/mbt-gen.rb +168 -38
- data/lib/solver-lib.rb +5 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 763d26c653134a8a5432753091e286e1df8aecf8c603a5eba5bc6980ed5c3e6f
|
|
4
|
+
data.tar.gz: e5e86c5368af05ff682fbd2f7bf7fed6a9e7909d7d92523728956ee3fee71946
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5c32f100cae06aa9f7e97d7e1b214f27a9d0747948feafddd01530392f45df0a9966e4f6ad3ef5be9a719b87f9e0bd91f966523415231b539026503aa1659064
|
|
7
|
+
data.tar.gz: 485bd1dfe0f01f7e553087603c90e73c582b7dd29de72cd79032f63f1b35df32af15c66369c540507ae4ed8427244159710076221dcf033696e7ce8732191ff7
|
data/lib/mbt-gen.rb
CHANGED
|
@@ -596,6 +596,15 @@ def translate_validation_rule_to_SMTLIB(rule, context_struct, prefix, config, op
|
|
|
596
596
|
field = resolve_field_path($1, context_struct, prefix)
|
|
597
597
|
filled_var_for_field(field)
|
|
598
598
|
end
|
|
599
|
+
.gsub(/LIST_VALUE\[[^\]]*,[^\]]*\]/) do |m|
|
|
600
|
+
unless m =~ /LIST_VALUE\[([^\]]*),([^\]]*)\]/ then
|
|
601
|
+
raise RuntimeError.new("could not parse LIST_VALUE_FIRST_ELEMENT[...]: #{m.inspect} in validation rule #{rule_name}")
|
|
602
|
+
end
|
|
603
|
+
xpath = $1
|
|
604
|
+
index = Integer($2)
|
|
605
|
+
l = resolve_field_path(xpath, context_struct, prefix)
|
|
606
|
+
value_var_for_list(l, index)
|
|
607
|
+
end
|
|
599
608
|
.gsub(/VALUE\[[^\]]*\]/) do |m|
|
|
600
609
|
unless m =~ /VALUE\[([^\]]*)\]/ then
|
|
601
610
|
raise RuntimeError.new("could not parse VALUE[...]: #{m.inspect} in validation rule #{rule_name}")
|
|
@@ -630,15 +639,6 @@ def translate_validation_rule_to_SMTLIB(rule, context_struct, prefix, config, op
|
|
|
630
639
|
end
|
|
631
640
|
"(or #{terms.join(" ")})"
|
|
632
641
|
end
|
|
633
|
-
.gsub(/LIST_VALUE\[[^\]]*,[^\]]*\]/) do |m|
|
|
634
|
-
unless m =~ /LIST_VALUE\[([^\]]*),([^\]]*)\]/ then
|
|
635
|
-
raise RuntimeError.new("could not parse LIST_VALUE_FIRST_ELEMENT[...]: #{m.inspect} in validation rule #{rule_name}")
|
|
636
|
-
end
|
|
637
|
-
xpath = $1
|
|
638
|
-
index = Integer($2)
|
|
639
|
-
l = resolve_field_path(xpath, context_struct, prefix)
|
|
640
|
-
value_var_for_list(l, index)
|
|
641
|
-
end
|
|
642
642
|
.gsub(/LIST_VALUE_FIRST_ELEMENT\[[^\]]*\]/) do |m| # DEPRECATED! Please use LIST_VALUE[...] instead.
|
|
643
643
|
unless m =~ /LIST_VALUE_FIRST_ELEMENT\[([^\]]*)\]/ then
|
|
644
644
|
raise RuntimeError.new("could not parse LIST_VALUE_FIRST_ELEMENT[...]: #{m.inspect} in validation rule #{rule_name}")
|
|
@@ -768,9 +768,9 @@ def parse_field_value(fielddef, value)
|
|
|
768
768
|
when :int
|
|
769
769
|
return Integer(value)
|
|
770
770
|
when :string
|
|
771
|
-
return value
|
|
771
|
+
return solver_value_to_string(value)
|
|
772
772
|
when :enum
|
|
773
|
-
return value
|
|
773
|
+
return solver_value_to_string(value)
|
|
774
774
|
when :date
|
|
775
775
|
return Date.parse(value)
|
|
776
776
|
when :timestamp
|
|
@@ -778,6 +778,10 @@ def parse_field_value(fielddef, value)
|
|
|
778
778
|
end
|
|
779
779
|
end
|
|
780
780
|
|
|
781
|
+
def solver_value_to_ruby_value(fielddef, solver_value)
|
|
782
|
+
parse_field_value(fielddef, solver_value)
|
|
783
|
+
end
|
|
784
|
+
|
|
781
785
|
def solver_value_to_string(solver_value)
|
|
782
786
|
if solver_value =~ /\"(.*)\"/ then
|
|
783
787
|
return $1
|
|
@@ -786,6 +790,15 @@ def solver_value_to_string(solver_value)
|
|
|
786
790
|
end
|
|
787
791
|
end
|
|
788
792
|
|
|
793
|
+
def format_solver_value(fielddef, solver_value)
|
|
794
|
+
if fielddef[:formatter] then
|
|
795
|
+
fvalue_ruby = solver_value_to_ruby_value(fielddef, solver_value)
|
|
796
|
+
fvalue_str = fielddef[:formatter].call(fvalue_ruby)
|
|
797
|
+
else
|
|
798
|
+
fvalue_str = solver_value_to_string(solver_value)
|
|
799
|
+
end
|
|
800
|
+
end
|
|
801
|
+
|
|
789
802
|
def build_document_from_model(progress, struct, model)
|
|
790
803
|
doc = Nokogiri::XML(XML_TEMPLATE)
|
|
791
804
|
add_model_struct_to_doc(progress, struct, doc, model)
|
|
@@ -806,7 +819,8 @@ def add_model_struct_to_doc(progress, struct, doc, model, prefix = nil)
|
|
|
806
819
|
raise RuntimeError.new("xpath '#{xpath}' not contained in model.")
|
|
807
820
|
end
|
|
808
821
|
if model_value[:filled] == true || model_value[:filled] == "true" then
|
|
809
|
-
|
|
822
|
+
fvalue_str = format_solver_value(value, model_value[:value])
|
|
823
|
+
doc.add_child("<#{key}>#{fvalue_str}</#{key}>")
|
|
810
824
|
end
|
|
811
825
|
elsif value[:type] == :list then
|
|
812
826
|
node = doc.add_child("<#{key}></#{key}>")
|
|
@@ -1171,17 +1185,43 @@ def list_validation_rules(message)
|
|
|
1171
1185
|
rules.each { |r| puts " #{r}" }
|
|
1172
1186
|
end
|
|
1173
1187
|
|
|
1174
|
-
def
|
|
1175
|
-
if
|
|
1188
|
+
def default_parser_for_type(value_str, datatype)
|
|
1189
|
+
if datatype == :string or datatype == :enum then
|
|
1190
|
+
value_str
|
|
1191
|
+
elsif datatype == :int then
|
|
1192
|
+
Integer(value_str)
|
|
1193
|
+
elsif datatype == :date then
|
|
1194
|
+
Date.parse(value_str)
|
|
1195
|
+
elsif datatype == :timestamp then
|
|
1196
|
+
Time.new(value_str)
|
|
1197
|
+
else
|
|
1198
|
+
raise RuntimeError.new("encountered unknown :datatype #{datatype.inspect}")
|
|
1199
|
+
end
|
|
1200
|
+
end
|
|
1201
|
+
|
|
1202
|
+
def value_of_type_to_solver(value, datatype)
|
|
1203
|
+
if datatype == :string || datatype == :enum then
|
|
1176
1204
|
"\"#{value}\""
|
|
1177
|
-
elsif
|
|
1205
|
+
elsif datatype == :int then
|
|
1178
1206
|
value.to_s
|
|
1179
|
-
elsif
|
|
1180
|
-
(
|
|
1181
|
-
elsif
|
|
1182
|
-
(
|
|
1207
|
+
elsif datatype == :date then
|
|
1208
|
+
(value - Time.at(0).to_date).to_i.to_s
|
|
1209
|
+
elsif datatype == :timestamp then
|
|
1210
|
+
(value - Time.at(0)).to_i.to_s
|
|
1183
1211
|
else
|
|
1184
|
-
raise RuntimeError.new("encountered unknown :
|
|
1212
|
+
raise RuntimeError.new("encountered value of unknown type: #{datatype.inspect}")
|
|
1213
|
+
end
|
|
1214
|
+
end
|
|
1215
|
+
|
|
1216
|
+
def value_of_type(value, type)
|
|
1217
|
+
value_of_type_to_solver(default_parser_for_type(value, type), type)
|
|
1218
|
+
end
|
|
1219
|
+
|
|
1220
|
+
def parse_field_value_to_ruby(fielddef, fieldvalue)
|
|
1221
|
+
if fielddef[:parser] then
|
|
1222
|
+
fielddef[:parser].call(fieldvalue)
|
|
1223
|
+
else
|
|
1224
|
+
default_parser_for_type(fieldvalue, fielddef[:datatype])
|
|
1185
1225
|
end
|
|
1186
1226
|
end
|
|
1187
1227
|
|
|
@@ -1716,6 +1756,16 @@ def validate_model(message, prefix=nil)
|
|
|
1716
1756
|
unless value[:datatype] then
|
|
1717
1757
|
raise RuntimeError.new("Model Problem: encountered field without a :datatype (key=#{key.inspect}, value=#{value.inspect})")
|
|
1718
1758
|
end
|
|
1759
|
+
if value[:parser] then
|
|
1760
|
+
unless value[:formatter] then
|
|
1761
|
+
raise RuntimeError.new("Model Problem: encountered field has a :parser, but no :formatter (key=#{key.inspect}, value=#{value.inspect})")
|
|
1762
|
+
end
|
|
1763
|
+
end
|
|
1764
|
+
if value[:formatter] then
|
|
1765
|
+
unless value[:parser] then
|
|
1766
|
+
raise RuntimeError.new("Model Problem: encountered field has a :formatter, but no :parser (key=#{key.inspect}, value=#{value.inspect})")
|
|
1767
|
+
end
|
|
1768
|
+
end
|
|
1719
1769
|
if value[:datatype] == :enum then
|
|
1720
1770
|
unless value[:values] then
|
|
1721
1771
|
raise RuntimeError.new("Model Problem: encountered enum field without a :values (key=#{key.inspect}, value=#{value.inspect})")
|
|
@@ -1723,7 +1773,13 @@ def validate_model(message, prefix=nil)
|
|
|
1723
1773
|
end
|
|
1724
1774
|
elsif value[:type] == :list then
|
|
1725
1775
|
unless value[:datatype] then
|
|
1726
|
-
raise RuntimeError.new("Model Problem: encountered list without
|
|
1776
|
+
raise RuntimeError.new("Model Problem: encountered list without :datatype property (key=#{key.inspect}, value=#{value.inspect})")
|
|
1777
|
+
end
|
|
1778
|
+
unless value[:model_maxLength] then
|
|
1779
|
+
raise RuntimeError.new("Model Problem: encountered list without :model_maxLength property (key=#{key.inspect}, value=#{value.inspect})")
|
|
1780
|
+
end
|
|
1781
|
+
unless value[:xpath_element] then
|
|
1782
|
+
raise RuntimeError.new("Model Problem: encountered list without :xpath_element property (key=#{key.inspect}, value=#{value.inspect})")
|
|
1727
1783
|
end
|
|
1728
1784
|
if value[:datatype] == :enum then
|
|
1729
1785
|
unless value[:values] then
|
|
@@ -1797,11 +1853,11 @@ end
|
|
|
1797
1853
|
def validate_schema_against_doc_struct(struct, doc, prefix = nil)
|
|
1798
1854
|
struct.each do |key, value|
|
|
1799
1855
|
next if key == :additional_smtlib || key == :validation_rules || key == :predicates || key == :parent_link || key == :struct_xpath_prefix
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1856
|
+
if prefix then
|
|
1857
|
+
xpath = "#{prefix}/#{key}"
|
|
1858
|
+
else
|
|
1859
|
+
xpath = key
|
|
1860
|
+
end
|
|
1805
1861
|
if value[:type] == :structure then
|
|
1806
1862
|
node = doc.at_xpath(key.to_s)
|
|
1807
1863
|
if node then
|
|
@@ -1832,6 +1888,26 @@ def validate_schema_against_doc_struct(struct, doc, prefix = nil)
|
|
|
1832
1888
|
end
|
|
1833
1889
|
end
|
|
1834
1890
|
end
|
|
1891
|
+
elsif value[:type] == :objlist then
|
|
1892
|
+
if value[:optional] == false then
|
|
1893
|
+
unless doc.at_xpath(key.to_s) then
|
|
1894
|
+
raise FatalError.new("ERROR: schema validation failed: non-optional objlist #{xpath} not found in doc.")
|
|
1895
|
+
end
|
|
1896
|
+
end
|
|
1897
|
+
list = doc.at_xpath(key.to_s)
|
|
1898
|
+
if list then
|
|
1899
|
+
index = 0
|
|
1900
|
+
list.children.to_a.each_with_index do |c|
|
|
1901
|
+
next unless c.is_a?(Nokogiri::XML::Element)
|
|
1902
|
+
index += 1
|
|
1903
|
+
unless c.name == value[:xpath_element] then
|
|
1904
|
+
raise FatalError.new("ERROR: schema validation failed: encountered element #{c.name} in objlist #{xpath}, which should only contain #{value[:xpath_element]} elements.")
|
|
1905
|
+
end
|
|
1906
|
+
if c then
|
|
1907
|
+
validate_schema_against_doc_struct(value[:ref], c, "#{xpath}/#{value[:xpath_element]}[#{index}]" )
|
|
1908
|
+
end
|
|
1909
|
+
end
|
|
1910
|
+
end
|
|
1835
1911
|
else
|
|
1836
1912
|
raise RuntimeError.new("Model error: encountered element #{xpath} of unknown type: #{value[:type]}.")
|
|
1837
1913
|
end
|
|
@@ -1843,10 +1919,10 @@ def translate_doc_to_SMTLIB(progress, solver, struct, doc, hash = {})
|
|
|
1843
1919
|
config = hash[:config]
|
|
1844
1920
|
|
|
1845
1921
|
solver.to_solver(progress, "; --- Document: ---")
|
|
1846
|
-
translate_struct_in_doc_to_SMTLIB(progress, solver, struct, doc, nil, hash)
|
|
1922
|
+
translate_struct_in_doc_to_SMTLIB(progress, solver, struct, doc, nil, nil, hash)
|
|
1847
1923
|
end
|
|
1848
1924
|
|
|
1849
|
-
def translate_struct_in_doc_to_SMTLIB(progress, solver, struct, doc, prefix, hash = {})
|
|
1925
|
+
def translate_struct_in_doc_to_SMTLIB(progress, solver, struct, doc, prefix, var_prefix, hash = {})
|
|
1850
1926
|
options = hash[:options]
|
|
1851
1927
|
config = hash[:config]
|
|
1852
1928
|
|
|
@@ -1857,6 +1933,11 @@ def translate_struct_in_doc_to_SMTLIB(progress, solver, struct, doc, prefix, has
|
|
|
1857
1933
|
else
|
|
1858
1934
|
xpath = key.to_s
|
|
1859
1935
|
end
|
|
1936
|
+
if var_prefix then
|
|
1937
|
+
var_xpath = "#{var_prefix}/#{key.to_s}"
|
|
1938
|
+
else
|
|
1939
|
+
var_xpath = key.to_s
|
|
1940
|
+
end
|
|
1860
1941
|
if value[:type] == :structure then
|
|
1861
1942
|
node = doc.at_xpath(xpath)
|
|
1862
1943
|
if node then
|
|
@@ -1866,9 +1947,9 @@ def translate_struct_in_doc_to_SMTLIB(progress, solver, struct, doc, prefix, has
|
|
|
1866
1947
|
}
|
|
1867
1948
|
assertionID = "doc-#{xpath.gsub('/', '-')}"
|
|
1868
1949
|
solver.associateAssertionIDWith(assertionID, info)
|
|
1869
|
-
solver.to_solver(progress, "(assert (! (= #{exists_var_for_structure(
|
|
1950
|
+
solver.to_solver(progress, "(assert (! (= #{exists_var_for_structure(var_xpath)} true) :named #{assertionID}))")
|
|
1870
1951
|
|
|
1871
|
-
translate_struct_in_doc_to_SMTLIB(progress, solver, value[:ref], doc, xpath, hash)
|
|
1952
|
+
translate_struct_in_doc_to_SMTLIB(progress, solver, value[:ref], doc, xpath, var_xpath, hash)
|
|
1872
1953
|
else
|
|
1873
1954
|
info = {
|
|
1874
1955
|
:assertion_type => :doc_structure_not_exists,
|
|
@@ -1876,7 +1957,7 @@ def translate_struct_in_doc_to_SMTLIB(progress, solver, struct, doc, prefix, has
|
|
|
1876
1957
|
}
|
|
1877
1958
|
assertionID = "doc-#{xpath.gsub('/', '-')}"
|
|
1878
1959
|
solver.associateAssertionIDWith(assertionID, info)
|
|
1879
|
-
solver.to_solver(progress, "(assert (! (= #{exists_var_for_structure(
|
|
1960
|
+
solver.to_solver(progress, "(assert (! (= #{exists_var_for_structure(var_xpath)} false) :named #{assertionID}))")
|
|
1880
1961
|
end
|
|
1881
1962
|
elsif value[:type] == :field then
|
|
1882
1963
|
node = doc.at_xpath(xpath)
|
|
@@ -1887,10 +1968,11 @@ def translate_struct_in_doc_to_SMTLIB(progress, solver, struct, doc, prefix, has
|
|
|
1887
1968
|
:xpath => xpath,
|
|
1888
1969
|
:value => fvalue
|
|
1889
1970
|
}
|
|
1890
|
-
|
|
1891
|
-
|
|
1971
|
+
fvalue_ruby = parse_field_value_to_ruby(value, fvalue)
|
|
1972
|
+
fvalue_str = value_of_type_to_solver(fvalue_ruby, value[:datatype])
|
|
1973
|
+
assertionID = "doc-#{var_xpath.gsub('/', '-')}"
|
|
1892
1974
|
solver.associateAssertionIDWith(assertionID, info)
|
|
1893
|
-
solver.to_solver(progress, "(assert (! (and (= #{filled_var_for_field(
|
|
1975
|
+
solver.to_solver(progress, "(assert (! (and (= #{filled_var_for_field(var_xpath)} true) (= #{value_var_for_field(var_xpath)} #{fvalue_str})) :named #{assertionID}))")
|
|
1894
1976
|
else
|
|
1895
1977
|
info = {
|
|
1896
1978
|
:assertion_type => :doc_field_empty,
|
|
@@ -1898,7 +1980,7 @@ def translate_struct_in_doc_to_SMTLIB(progress, solver, struct, doc, prefix, has
|
|
|
1898
1980
|
}
|
|
1899
1981
|
assertionID = "doc-#{xpath.gsub('/', '-')}"
|
|
1900
1982
|
solver.associateAssertionIDWith(assertionID, info)
|
|
1901
|
-
solver.to_solver(progress, "(assert (! (= #{filled_var_for_field(
|
|
1983
|
+
solver.to_solver(progress, "(assert (! (= #{filled_var_for_field(var_xpath)} false) :named #{assertionID}))")
|
|
1902
1984
|
end
|
|
1903
1985
|
elsif value[:type] == :list then
|
|
1904
1986
|
node = doc.at_xpath(xpath)
|
|
@@ -1913,14 +1995,62 @@ def translate_struct_in_doc_to_SMTLIB(progress, solver, struct, doc, prefix, has
|
|
|
1913
1995
|
:xpath => xpath,
|
|
1914
1996
|
:values => fvalues
|
|
1915
1997
|
}
|
|
1916
|
-
fvalue_str = value_of_type(fvalues, value[:datatype])
|
|
1917
1998
|
assertionID = "doc-#{xpath.gsub('/', '-')}"
|
|
1918
1999
|
solver.associateAssertionIDWith(assertionID, info)
|
|
1919
2000
|
clauses = []
|
|
1920
2001
|
fvalues.each_with_index do |fvalue, index|
|
|
1921
2002
|
clauses << "(= #{value_var_for_list(xpath,index)} #{value_of_type(fvalue, value[:datatype])})"
|
|
1922
2003
|
end
|
|
1923
|
-
solver.to_solver(progress, "(assert (! (and (= #{filled_var_for_field(
|
|
2004
|
+
solver.to_solver(progress, "(assert (! (and (= #{filled_var_for_field(var_xpath)} true) (= #{size_var_for_list(xpath)} #{fvalues.size}) #{clauses.join(' ')}) :named #{assertionID}))")
|
|
2005
|
+
else
|
|
2006
|
+
info = {
|
|
2007
|
+
:assertion_type => :doc_field_empty,
|
|
2008
|
+
:xpath => xpath,
|
|
2009
|
+
}
|
|
2010
|
+
assertionID = "doc-#{xpath.gsub('/', '-')}"
|
|
2011
|
+
solver.associateAssertionIDWith(assertionID, info)
|
|
2012
|
+
solver.to_solver(progress, "(assert (! (= #{filled_var_for_field(var_xpath)} false) :named #{assertionID}))")
|
|
2013
|
+
end
|
|
2014
|
+
elsif value[:type] == :objlist then
|
|
2015
|
+
node = doc.at_xpath(xpath)
|
|
2016
|
+
if node then
|
|
2017
|
+
fvalues = []
|
|
2018
|
+
index = 0
|
|
2019
|
+
num_elements = 0
|
|
2020
|
+
value[:model_maxLength].times do |index|
|
|
2021
|
+
element_node = node.at_xpath("#{value[:xpath_element]}[#{index+1}]")
|
|
2022
|
+
element_xpath = "#{xpath}/#{value[:xpath_element]}[#{index+1}]"
|
|
2023
|
+
element_var_xpath = "#{xpath}/#{index}"
|
|
2024
|
+
if element_node then
|
|
2025
|
+
num_elements += 1
|
|
2026
|
+
info = {
|
|
2027
|
+
:assertion_type => :doc_structure_exists,
|
|
2028
|
+
:xpath => element_xpath,
|
|
2029
|
+
}
|
|
2030
|
+
assertionID = "doc-#{element_var_xpath.gsub('/', '-')}"
|
|
2031
|
+
solver.associateAssertionIDWith(assertionID, info)
|
|
2032
|
+
solver.to_solver(progress, "(assert (! (= #{exists_var_for_structure(element_var_xpath)} true) :named #{assertionID}))")
|
|
2033
|
+
|
|
2034
|
+
translate_struct_in_doc_to_SMTLIB(progress, solver, value[:ref], doc, element_xpath, element_var_xpath, hash)
|
|
2035
|
+
else
|
|
2036
|
+
info = {
|
|
2037
|
+
:assertion_type => :doc_structure_not_exists,
|
|
2038
|
+
:xpath => element_xpath,
|
|
2039
|
+
}
|
|
2040
|
+
assertionID = "doc-#{element_var_xpath.gsub('/', '-')}"
|
|
2041
|
+
solver.associateAssertionIDWith(assertionID, info)
|
|
2042
|
+
solver.to_solver(progress, "(assert (! (= #{exists_var_for_structure(element_var_xpath)} false) :named #{assertionID}))")
|
|
2043
|
+
end
|
|
2044
|
+
end
|
|
2045
|
+
info = {
|
|
2046
|
+
:assertion_type => :doc_objlist_filled,
|
|
2047
|
+
:size => num_elements,
|
|
2048
|
+
:xpath => xpath
|
|
2049
|
+
}
|
|
2050
|
+
assertionID = "doc-#{xpath.gsub('/', '-')}"
|
|
2051
|
+
solver.associateAssertionIDWith(assertionID, info)
|
|
2052
|
+
clauses = []
|
|
2053
|
+
solver.to_solver(progress, "(assert (! (and (= #{filled_var_for_field(var_xpath)} true) (= #{size_var_for_list(var_xpath)} #{num_elements})) :named #{assertionID}))")
|
|
1924
2054
|
else
|
|
1925
2055
|
info = {
|
|
1926
2056
|
:assertion_type => :doc_field_empty,
|
|
@@ -1928,7 +2058,7 @@ def translate_struct_in_doc_to_SMTLIB(progress, solver, struct, doc, prefix, has
|
|
|
1928
2058
|
}
|
|
1929
2059
|
assertionID = "doc-#{xpath.gsub('/', '-')}"
|
|
1930
2060
|
solver.associateAssertionIDWith(assertionID, info)
|
|
1931
|
-
solver.to_solver(progress, "(assert (! (= #{filled_var_for_field(
|
|
2061
|
+
solver.to_solver(progress, "(assert (! (= #{filled_var_for_field(var_xpath)} false) :named #{assertionID}))")
|
|
1932
2062
|
end
|
|
1933
2063
|
else
|
|
1934
2064
|
raise RuntimeError.new("Model Error: encountered unknown type #{value[:type].inspect}")
|
data/lib/solver-lib.rb
CHANGED
|
@@ -225,7 +225,7 @@ class SolverFactory
|
|
|
225
225
|
unsat_core = session.from_solver(@progress)
|
|
226
226
|
explanation = session.parse_unsat_core(unsat_core)
|
|
227
227
|
else
|
|
228
|
-
ModelUtils.handleSolverError(@progress, options, result)
|
|
228
|
+
ModelUtils.handleSolverError(@progress, session, options, result)
|
|
229
229
|
end
|
|
230
230
|
|
|
231
231
|
return explanation
|
|
@@ -469,6 +469,10 @@ class Z3Solver
|
|
|
469
469
|
return "Structure #{info[:xpath]} exists in document"
|
|
470
470
|
elsif info[:assertion_type] == :doc_structure_not_exists then
|
|
471
471
|
return "Structure #{info[:xpath]} does not exist in document"
|
|
472
|
+
elsif info[:assertion_type] == :doc_list_filled then
|
|
473
|
+
return "List #{info[:xpath]} is filled in document and contains the values #{info[:values].inspect}"
|
|
474
|
+
elsif info[:assertion_type] == :doc_objlist_filled then
|
|
475
|
+
return "ObjList #{info[:xpath]} is filled in document and contains #{info[:size]} elements"
|
|
472
476
|
elsif info[:assertion_type] == :constraint then
|
|
473
477
|
if info[:constraint_type] == :min then
|
|
474
478
|
return "Field #{info[:xpath]} has a minimum value of #{info[:value]}."
|
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.
|
|
4
|
+
version: 0.0.8
|
|
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
|
+
date: 2026-08-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: nokogiri
|