adsl 0.0.3 → 0.1.0
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/Gemfile +2 -20
- data/README.md +14 -21
- data/bin/adsl-verify +8 -8
- data/lib/adsl.rb +3 -0
- data/lib/adsl/adsl.rb +3 -0
- data/lib/adsl/ds/data_store_spec.rb +339 -0
- data/lib/adsl/extract/instrumenter.rb +206 -0
- data/lib/adsl/extract/meta.rb +33 -0
- data/lib/adsl/extract/rails/action_block_builder.rb +233 -0
- data/lib/adsl/extract/rails/action_instrumenter.rb +400 -0
- data/lib/adsl/extract/rails/action_runner.rb +57 -0
- data/lib/adsl/extract/rails/active_record_metaclass_generator.rb +555 -0
- data/lib/adsl/extract/rails/callback_chain_simulator.rb +135 -0
- data/lib/adsl/extract/rails/invariant_extractor.rb +48 -0
- data/lib/adsl/extract/rails/invariant_instrumenter.rb +70 -0
- data/lib/adsl/extract/rails/other_meta.rb +57 -0
- data/lib/adsl/extract/rails/rails_extractor.rb +211 -0
- data/lib/adsl/extract/rails/rails_instrumentation_test_case.rb +34 -0
- data/lib/adsl/extract/rails/rails_special_gem_instrumentation.rb +120 -0
- data/lib/adsl/extract/rails/rails_test_helper.rb +140 -0
- data/lib/adsl/extract/sexp_utils.rb +54 -0
- data/lib/adsl/fol/first_order_logic.rb +261 -0
- data/lib/adsl/parser/adsl_parser.racc +159 -0
- data/lib/{parser → adsl/parser}/adsl_parser.rex +4 -4
- data/lib/{parser → adsl/parser}/adsl_parser.rex.rb +6 -6
- data/lib/adsl/parser/adsl_parser.tab.rb +1031 -0
- data/lib/adsl/parser/ast_nodes.rb +1410 -0
- data/lib/adsl/railtie.rb +67 -0
- data/lib/adsl/spass/bin.rb +230 -0
- data/lib/{spass → adsl/spass}/ruby_extensions.rb +0 -0
- data/lib/adsl/spass/spass_ds_extensions.rb +931 -0
- data/lib/adsl/spass/spass_translator.rb +393 -0
- data/lib/adsl/spass/util.rb +13 -0
- data/lib/adsl/util/csv_hash_formatter.rb +94 -0
- data/lib/adsl/util/general.rb +228 -0
- data/lib/adsl/util/test_helper.rb +71 -0
- data/lib/adsl/verification/formula_generators.rb +231 -0
- data/lib/adsl/verification/instrumentation_filter.rb +50 -0
- data/lib/adsl/verification/invariant.rb +19 -0
- data/lib/adsl/verification/rails_verification.rb +33 -0
- data/lib/adsl/verification/utils.rb +20 -0
- data/lib/adsl/verification/verification_case.rb +13 -0
- data/test/integration/rails/rails_branch_verification_test.rb +112 -0
- data/test/integration/rails/rails_verification_test.rb +253 -0
- data/test/integration/spass/basic_translation_test.rb +563 -0
- data/test/integration/spass/control_flow_translation_test.rb +421 -0
- data/test/unit/adsl/ds/data_store_spec_test.rb +54 -0
- data/test/unit/adsl/extract/instrumenter_test.rb +103 -0
- data/test/unit/adsl/extract/meta_test.rb +142 -0
- data/test/unit/adsl/extract/rails/action_block_builder_test.rb +178 -0
- data/test/unit/adsl/extract/rails/action_instrumenter_test.rb +68 -0
- data/test/unit/adsl/extract/rails/active_record_metaclass_generator_test.rb +336 -0
- data/test/unit/adsl/extract/rails/callback_chain_simulator_test.rb +76 -0
- data/test/unit/adsl/extract/rails/invariant_extractor_test.rb +92 -0
- data/test/unit/adsl/extract/rails/rails_extractor_test.rb +1380 -0
- data/test/unit/adsl/extract/rails/rails_test_helper_test.rb +25 -0
- data/test/unit/adsl/extract/sexp_utils_test.rb +100 -0
- data/test/unit/adsl/fol/first_order_logic_test.rb +227 -0
- data/test/unit/adsl/parser/action_parser_test.rb +1040 -0
- data/test/unit/adsl/parser/ast_nodes_test.rb +359 -0
- data/test/unit/adsl/parser/class_parser_test.rb +288 -0
- data/test/unit/adsl/parser/general_parser_test.rb +67 -0
- data/test/unit/adsl/parser/invariant_parser_test.rb +432 -0
- data/test/unit/adsl/parser/parser_util_test.rb +126 -0
- data/test/unit/adsl/spass/bin_test.rb +65 -0
- data/test/unit/adsl/spass/ruby_extensions_test.rb +39 -0
- data/test/unit/adsl/spass/spass_ds_extensions_test.rb +7 -0
- data/test/unit/adsl/spass/spass_translator_test.rb +342 -0
- data/test/unit/adsl/util/csv_hash_formatter_test.rb +68 -0
- data/test/unit/adsl/util/general_test.rb +303 -0
- data/test/unit/adsl/util/test_helper_test.rb +120 -0
- data/test/unit/adsl/verification/formula_generators_test.rb +200 -0
- data/test/unit/adsl/verification/instrumentation_filter_test.rb +39 -0
- data/test/unit/adsl/verification/utils_test.rb +39 -0
- data/test/unit/adsl/verification/verification_case_test.rb +8 -0
- metadata +229 -29
- data/lib/ds/data_store_spec.rb +0 -292
- data/lib/fol/first_order_logic.rb +0 -260
- data/lib/parser/adsl_ast.rb +0 -779
- data/lib/parser/adsl_parser.racc +0 -151
- data/lib/parser/adsl_parser.tab.rb +0 -976
- data/lib/parser/dsdl_parser.rex.rb +0 -196
- data/lib/parser/dsdl_parser.tab.rb +0 -976
- data/lib/spass/bin.rb +0 -164
- data/lib/spass/spass_ds_extensions.rb +0 -870
- data/lib/spass/spass_translator.rb +0 -388
- data/lib/spass/util.rb +0 -11
- data/lib/util/csv_hash_formatter.rb +0 -47
- data/lib/util/test_helper.rb +0 -33
- data/lib/util/util.rb +0 -114
|
@@ -0,0 +1,563 @@
|
|
|
1
|
+
require 'adsl/util/test_helper'
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
|
|
4
|
+
class BasicTranslationTest < Test::Unit::TestCase
|
|
5
|
+
include ADSL::FOL
|
|
6
|
+
|
|
7
|
+
def test_blank_data_store
|
|
8
|
+
adsl_assert :correct, <<-ADSL
|
|
9
|
+
action blah() {}
|
|
10
|
+
ADSL
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def test_not_creation__nothing_exists
|
|
14
|
+
adsl_assert :correct, <<-ADSL
|
|
15
|
+
class Class {}
|
|
16
|
+
action blah() {}
|
|
17
|
+
invariant not exists(Class o)
|
|
18
|
+
ADSL
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def test_not_creation__something_exists
|
|
22
|
+
adsl_assert :correct, <<-ADSL
|
|
23
|
+
class Class {}
|
|
24
|
+
action blah() {}
|
|
25
|
+
invariant exists(Class o)
|
|
26
|
+
ADSL
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def test_creating_objects__something_exists
|
|
30
|
+
adsl_assert :correct, <<-ADSL
|
|
31
|
+
class Class {}
|
|
32
|
+
action blah() {
|
|
33
|
+
create(Class)
|
|
34
|
+
}
|
|
35
|
+
invariant exists(Class o)
|
|
36
|
+
ADSL
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def test_creating_objects__nothing_exists
|
|
40
|
+
adsl_assert :incorrect, <<-ADSL
|
|
41
|
+
class Class {}
|
|
42
|
+
action blah() {
|
|
43
|
+
create(Class)
|
|
44
|
+
}
|
|
45
|
+
invariant not exists(Class o)
|
|
46
|
+
ADSL
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def test_creating_objects__of_exact_class
|
|
50
|
+
adsl_assert :correct, <<-ADSL
|
|
51
|
+
class Parent {}
|
|
52
|
+
class Child extends Parent {}
|
|
53
|
+
action blah() {
|
|
54
|
+
create(Parent)
|
|
55
|
+
}
|
|
56
|
+
invariant not exists(Child o)
|
|
57
|
+
ADSL
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def test_classtypes
|
|
61
|
+
conjecture = ForAll.new(:o, Not.new(And.new('of_Class1_type(o)', 'of_Class2_type(o)')))
|
|
62
|
+
adsl_assert :correct, <<-ADSL, :conjecture => conjecture
|
|
63
|
+
class Class1 {}
|
|
64
|
+
class Class2 {}
|
|
65
|
+
action blah() {}
|
|
66
|
+
ADSL
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def test_classtypes_polymorphism__no_contradictions
|
|
70
|
+
conjecture = Or.new(
|
|
71
|
+
Not.new(Exists.new(:o, 'of_Parent_type(o)')),
|
|
72
|
+
Not.new(Exists.new(:o, 'of_Child1_type(o)')),
|
|
73
|
+
Not.new(Exists.new(:o, 'of_Child2_type(o)')),
|
|
74
|
+
Not.new(Exists.new(:o, 'of_SubChild_type(o)')),
|
|
75
|
+
Not.new(Exists.new(:o, 'of_Parent2_type(o)'))
|
|
76
|
+
)
|
|
77
|
+
adsl_assert :incorrect, <<-ADSL, :conjecture => conjecture
|
|
78
|
+
class Parent {}
|
|
79
|
+
class Child1 extends Parent {}
|
|
80
|
+
class Child2 extends Parent {}
|
|
81
|
+
class SubChild extends Child1 {}
|
|
82
|
+
class Parent2 {}
|
|
83
|
+
action blah() {}
|
|
84
|
+
ADSL
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def test_classtypes_polymorphism
|
|
88
|
+
type_spec = <<-ADSL
|
|
89
|
+
class Parent {}
|
|
90
|
+
class Child1 extends Parent {}
|
|
91
|
+
class Child2 extends Parent {}
|
|
92
|
+
class SubChild extends Child1 {}
|
|
93
|
+
class Parent2 {}
|
|
94
|
+
action blah() {}
|
|
95
|
+
ADSL
|
|
96
|
+
|
|
97
|
+
conjecture = ForAll.new(:o, Implies.new('of_Child1_type(o)', 'of_Parent_type(o)'))
|
|
98
|
+
adsl_assert :correct, type_spec, :conjecture => conjecture
|
|
99
|
+
|
|
100
|
+
conjecture = ForAll.new(:o, Implies.new(Not.new('of_Child1_type(o)'), 'of_Parent_type(o)'))
|
|
101
|
+
adsl_assert :incorrect, type_spec, :conjecture => conjecture
|
|
102
|
+
|
|
103
|
+
conjecture = ForAll.new(:o, Implies.new(Not.new('of_Parent_type(o)'), And.new(
|
|
104
|
+
Not.new('of_Child1_type(o)'),
|
|
105
|
+
Not.new('of_Child2_type(o)')
|
|
106
|
+
)))
|
|
107
|
+
adsl_assert :correct, type_spec, :conjecture => conjecture
|
|
108
|
+
|
|
109
|
+
conjecture = ForAll.new(:o, Not.new(And.new('of_Child1_type(o)', 'of_Parent2_type(o)')))
|
|
110
|
+
adsl_assert :correct, type_spec, :conjecture => conjecture
|
|
111
|
+
|
|
112
|
+
conjecture = ForAll.new(:o, Implies.new('of_SubChild_type(o)', 'of_Child1_type(o)'))
|
|
113
|
+
adsl_assert :correct, type_spec, :conjecture => conjecture
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def test_multiple_invariants
|
|
117
|
+
adsl_assert :correct, <<-ADSL
|
|
118
|
+
class Class {}
|
|
119
|
+
action blah() {
|
|
120
|
+
create(Class)
|
|
121
|
+
}
|
|
122
|
+
invariant true
|
|
123
|
+
invariant true
|
|
124
|
+
invariant exists(Class o)
|
|
125
|
+
ADSL
|
|
126
|
+
adsl_assert :incorrect, <<-ADSL
|
|
127
|
+
class Class {}
|
|
128
|
+
action blah() {
|
|
129
|
+
create(Class)
|
|
130
|
+
}
|
|
131
|
+
invariant true
|
|
132
|
+
invariant not exists(Class o)
|
|
133
|
+
invariant true
|
|
134
|
+
ADSL
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def test_variables__any_cardinality
|
|
138
|
+
adsl_assert :incorrect, <<-ADSL
|
|
139
|
+
class Class {}
|
|
140
|
+
action blah(0+ Class var) {
|
|
141
|
+
delete var
|
|
142
|
+
}
|
|
143
|
+
invariant exists(Class o)
|
|
144
|
+
ADSL
|
|
145
|
+
adsl_assert :correct, <<-ADSL
|
|
146
|
+
class Class {}
|
|
147
|
+
action blah(0+ Class var) {
|
|
148
|
+
delete var
|
|
149
|
+
}
|
|
150
|
+
invariant not exists(Class o)
|
|
151
|
+
ADSL
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def test_variables__cardinality_constraint
|
|
155
|
+
adsl_assert :correct, <<-ADSL
|
|
156
|
+
class Class {}
|
|
157
|
+
action blah(0..1 Class var) {
|
|
158
|
+
create(Class)
|
|
159
|
+
delete var
|
|
160
|
+
}
|
|
161
|
+
invariant exists(Class o)
|
|
162
|
+
ADSL
|
|
163
|
+
adsl_assert :correct, <<-ADSL
|
|
164
|
+
class Class {}
|
|
165
|
+
action blah(1 Class var) {
|
|
166
|
+
create(Class)
|
|
167
|
+
delete var
|
|
168
|
+
}
|
|
169
|
+
invariant exists(Class o)
|
|
170
|
+
invariant forall(Class o1, Class o2: o1 == o2)
|
|
171
|
+
ADSL
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def test_no_creation_objects__forall_does_not_imply_exists
|
|
175
|
+
adsl_assert :correct, <<-ADSL
|
|
176
|
+
class Class {}
|
|
177
|
+
action blah() {}
|
|
178
|
+
invariant forall(Class o1, Class o2: o1 == o2)
|
|
179
|
+
invariant not exists(Class o)
|
|
180
|
+
ADSL
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def test_creation__add_objects_to_max_one_object
|
|
184
|
+
adsl_assert :incorrect, <<-ADSL
|
|
185
|
+
class Class {}
|
|
186
|
+
action blah() {
|
|
187
|
+
create(Class)
|
|
188
|
+
}
|
|
189
|
+
invariant forall(Class o1, Class o2: o1 == o2)
|
|
190
|
+
ADSL
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def test_creation__add_two_objects_adds_two_objects
|
|
194
|
+
adsl_assert :incorrect, <<-ADSL
|
|
195
|
+
class Class { 0+ Class relation }
|
|
196
|
+
action blah() {
|
|
197
|
+
create(Class).relation += create(Class)
|
|
198
|
+
delete oneof(allof(Class))
|
|
199
|
+
}
|
|
200
|
+
invariant forall(Class o1, Class o2: o1 == o2)
|
|
201
|
+
ADSL
|
|
202
|
+
adsl_assert :correct, <<-ADSL
|
|
203
|
+
class Class { 0+ Class relation }
|
|
204
|
+
action blah() {
|
|
205
|
+
create(Class).relation += create(Class)
|
|
206
|
+
delete oneof(allof(Class))
|
|
207
|
+
delete oneof(allof(Class))
|
|
208
|
+
}
|
|
209
|
+
invariant forall(Class o1, Class o2: o1 == o2)
|
|
210
|
+
ADSL
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def test_creation__class_specific
|
|
214
|
+
adsl_assert :correct, <<-ADSL
|
|
215
|
+
class Class {}
|
|
216
|
+
class Class2 {}
|
|
217
|
+
action blah() {
|
|
218
|
+
create(Class2)
|
|
219
|
+
}
|
|
220
|
+
invariant forall(Class o1, Class o2: o1 == o2)
|
|
221
|
+
ADSL
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def test_deletion__empty_data_store
|
|
225
|
+
adsl_assert :correct, <<-ADSL
|
|
226
|
+
class Class {}
|
|
227
|
+
action blah() {
|
|
228
|
+
delete allof(Class)
|
|
229
|
+
}
|
|
230
|
+
invariant not exists(Class c)
|
|
231
|
+
ADSL
|
|
232
|
+
adsl_assert :incorrect, <<-ADSL
|
|
233
|
+
class Class {}
|
|
234
|
+
action blah() {
|
|
235
|
+
delete allof(Class)
|
|
236
|
+
}
|
|
237
|
+
invariant exists(Class c)
|
|
238
|
+
ADSL
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def test_deletion__create_delete_data_store
|
|
242
|
+
adsl_assert :correct, <<-ADSL
|
|
243
|
+
class Class {}
|
|
244
|
+
action blah() {
|
|
245
|
+
create(Class)
|
|
246
|
+
delete allof(Class)
|
|
247
|
+
}
|
|
248
|
+
invariant not exists(Class c)
|
|
249
|
+
ADSL
|
|
250
|
+
adsl_assert :incorrect, <<-ADSL
|
|
251
|
+
class Class {}
|
|
252
|
+
action blah() {
|
|
253
|
+
create(Class)
|
|
254
|
+
delete allof(Class)
|
|
255
|
+
}
|
|
256
|
+
invariant exists(Class c)
|
|
257
|
+
ADSL
|
|
258
|
+
adsl_assert :incorrect, <<-ADSL
|
|
259
|
+
class Class {}
|
|
260
|
+
action blah() {
|
|
261
|
+
delete allof(Class)
|
|
262
|
+
create(Class)
|
|
263
|
+
}
|
|
264
|
+
invariant not exists(Class c)
|
|
265
|
+
ADSL
|
|
266
|
+
adsl_assert :correct, <<-ADSL
|
|
267
|
+
class Class {}
|
|
268
|
+
action blah() {
|
|
269
|
+
delete allof(Class)
|
|
270
|
+
create(Class)
|
|
271
|
+
}
|
|
272
|
+
invariant exists(Class c)
|
|
273
|
+
ADSL
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
def test_subset__invariant
|
|
277
|
+
adsl_assert :correct, <<-ADSL
|
|
278
|
+
class Class {}
|
|
279
|
+
action blah() {}
|
|
280
|
+
invariant subset(allof(Class)) in allof(Class)
|
|
281
|
+
ADSL
|
|
282
|
+
adsl_assert :incorrect, <<-ADSL
|
|
283
|
+
class Class {}
|
|
284
|
+
action blah() {}
|
|
285
|
+
invariant subset(allof(Class)) in subset(allof(Class))
|
|
286
|
+
ADSL
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
def test_variable__basic
|
|
290
|
+
adsl_assert :incorrect, <<-ADSL
|
|
291
|
+
class Class {}
|
|
292
|
+
action blah() {
|
|
293
|
+
a = allof(Class)
|
|
294
|
+
delete a
|
|
295
|
+
}
|
|
296
|
+
invariant exists(Class c)
|
|
297
|
+
ADSL
|
|
298
|
+
adsl_assert :correct, <<-ADSL
|
|
299
|
+
class Class {}
|
|
300
|
+
action blah() {
|
|
301
|
+
a = allof(Class)
|
|
302
|
+
delete a
|
|
303
|
+
}
|
|
304
|
+
invariant not exists(Class c)
|
|
305
|
+
ADSL
|
|
306
|
+
adsl_assert :incorrect, <<-ADSL
|
|
307
|
+
class Class {}
|
|
308
|
+
action blah() {
|
|
309
|
+
a = subset(allof(Class))
|
|
310
|
+
delete a
|
|
311
|
+
}
|
|
312
|
+
invariant exists(Class c)
|
|
313
|
+
ADSL
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
def test_create__assignment
|
|
317
|
+
adsl_assert :correct, <<-ADSL
|
|
318
|
+
class Class {}
|
|
319
|
+
action blah() {
|
|
320
|
+
a = create(Class)
|
|
321
|
+
delete a
|
|
322
|
+
}
|
|
323
|
+
invariant not exists(Class c)
|
|
324
|
+
ADSL
|
|
325
|
+
adsl_assert :incorrect, <<-ADSL
|
|
326
|
+
class Class {}
|
|
327
|
+
action blah() {
|
|
328
|
+
a = create(Class)
|
|
329
|
+
b = create(Class)
|
|
330
|
+
delete a
|
|
331
|
+
}
|
|
332
|
+
invariant not exists(Class c)
|
|
333
|
+
ADSL
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
def test_oneof__is_one_object
|
|
337
|
+
adsl_assert :correct, <<-ADSL
|
|
338
|
+
class Class {}
|
|
339
|
+
action blah() {
|
|
340
|
+
create(Class)
|
|
341
|
+
delete oneof(allof(Class))
|
|
342
|
+
}
|
|
343
|
+
invariant exists(Class c)
|
|
344
|
+
ADSL
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
def test_is_empty
|
|
348
|
+
adsl_assert :correct, <<-ADSL
|
|
349
|
+
class Class {}
|
|
350
|
+
action blah() {
|
|
351
|
+
delete allof(Class)
|
|
352
|
+
}
|
|
353
|
+
invariant empty(allof(Class))
|
|
354
|
+
ADSL
|
|
355
|
+
adsl_assert :correct, <<-ADSL
|
|
356
|
+
class Class {}
|
|
357
|
+
action blah() {}
|
|
358
|
+
invariant empty(allof(Class))
|
|
359
|
+
ADSL
|
|
360
|
+
adsl_assert :incorrect, <<-ADSL
|
|
361
|
+
class Class {}
|
|
362
|
+
action blah() {
|
|
363
|
+
create(Class)
|
|
364
|
+
}
|
|
365
|
+
invariant empty(allof(Class))
|
|
366
|
+
ADSL
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
def test_deref
|
|
370
|
+
adsl_assert :correct, <<-ADSL
|
|
371
|
+
class Class { 0+ Class2 rel }
|
|
372
|
+
class Class2 {}
|
|
373
|
+
action blah() {
|
|
374
|
+
delete allof(Class).rel
|
|
375
|
+
}
|
|
376
|
+
invariant forall(Class o: empty(o.rel))
|
|
377
|
+
ADSL
|
|
378
|
+
adsl_assert :incorrect, <<-ADSL
|
|
379
|
+
class Class { 0+ Class2 rel }
|
|
380
|
+
class Class2 {}
|
|
381
|
+
action blah() {
|
|
382
|
+
delete allof(Class).rel
|
|
383
|
+
}
|
|
384
|
+
invariant not forall(Class o: empty(o.rel))
|
|
385
|
+
ADSL
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
def test_deref_polymorphic
|
|
389
|
+
adsl_assert :incorrect, <<-ADSL
|
|
390
|
+
class Parent { 0+ Parent rel }
|
|
391
|
+
class Child extends Parent {}
|
|
392
|
+
action blah() {
|
|
393
|
+
delete allof(Parent).rel
|
|
394
|
+
}
|
|
395
|
+
invariant exists(Child o: not empty(o.rel))
|
|
396
|
+
ADSL
|
|
397
|
+
adsl_assert :incorrect, <<-ADSL
|
|
398
|
+
class Parent { 0+ Parent rel }
|
|
399
|
+
class Child extends Parent {}
|
|
400
|
+
action blah() {
|
|
401
|
+
delete allof(Child).rel
|
|
402
|
+
}
|
|
403
|
+
invariant exists(Child o: not empty(o.rel))
|
|
404
|
+
ADSL
|
|
405
|
+
adsl_assert :correct, <<-ADSL
|
|
406
|
+
class Parent { 0+ Parent rel }
|
|
407
|
+
class Child extends Parent {}
|
|
408
|
+
action blah() {
|
|
409
|
+
delete allof(Child).rel
|
|
410
|
+
}
|
|
411
|
+
invariant exists(Parent o: not empty(o.rel)) and not exists(Child o: not empty(o.rel))
|
|
412
|
+
ADSL
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
def test__create_ref
|
|
416
|
+
adsl_assert :correct, <<-ADSL
|
|
417
|
+
class Class{ 0+ Class rel }
|
|
418
|
+
action blah() {
|
|
419
|
+
v1 = oneof (allof(Class))
|
|
420
|
+
v2 = oneof (allof(Class))
|
|
421
|
+
v1.rel += v2
|
|
422
|
+
}
|
|
423
|
+
invariant exists(Class o: not empty(o.rel))
|
|
424
|
+
ADSL
|
|
425
|
+
adsl_assert :incorrect, <<-ADSL
|
|
426
|
+
class Class{ 0+ Class rel }
|
|
427
|
+
action blah() {
|
|
428
|
+
v1 = oneof (allof(Class))
|
|
429
|
+
v2 = oneof (allof(Class))
|
|
430
|
+
v1.rel += v2
|
|
431
|
+
}
|
|
432
|
+
invariant forall(Class o: empty(o.rel))
|
|
433
|
+
ADSL
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
def test__create_ref_clique
|
|
437
|
+
adsl_assert :correct, <<-adsl
|
|
438
|
+
class Class{ 0+ Class rel }
|
|
439
|
+
action blah() {
|
|
440
|
+
allof(Class).rel += allof(Class)
|
|
441
|
+
}
|
|
442
|
+
invariant forall(Class v: v.rel == allof(Class))
|
|
443
|
+
adsl
|
|
444
|
+
|
|
445
|
+
conjecture = <<-SPASS
|
|
446
|
+
forall( [o1, o2], implies(
|
|
447
|
+
and(exists_finally(o1), exists_finally(o2), is_object(o1), is_object(o2)),
|
|
448
|
+
exists( [r], and(left_link_Class_rel(r, o1), right_link_Class_rel(r, o2)))
|
|
449
|
+
))
|
|
450
|
+
SPASS
|
|
451
|
+
adsl_assert(:correct, <<-adsl, :conjecture => conjecture)
|
|
452
|
+
class Class{ 0+ Class rel }
|
|
453
|
+
action blah() {
|
|
454
|
+
allof(Class).rel += allof(Class)
|
|
455
|
+
}
|
|
456
|
+
invariant forall(Class v: v.rel == allof(Class))
|
|
457
|
+
adsl
|
|
458
|
+
|
|
459
|
+
adsl_assert :incorrect, <<-ADSL
|
|
460
|
+
class Class{ 0+ Class rel }
|
|
461
|
+
action blah() {
|
|
462
|
+
allof(Class).rel += allof(Class)
|
|
463
|
+
}
|
|
464
|
+
invariant !forall(Class v: v.rel == allof(Class))
|
|
465
|
+
ADSL
|
|
466
|
+
end
|
|
467
|
+
|
|
468
|
+
def test__no_refs_on_new_object
|
|
469
|
+
adsl_assert :correct, <<-ADSL
|
|
470
|
+
class Class { 0+ Class rel }
|
|
471
|
+
action blah() {
|
|
472
|
+
create(Class)
|
|
473
|
+
}
|
|
474
|
+
invariant exists(Class o: empty(o.rel))
|
|
475
|
+
ADSL
|
|
476
|
+
adsl_assert :incorrect, <<-ADSL
|
|
477
|
+
class Class { 0+ Class rel }
|
|
478
|
+
action blah() {
|
|
479
|
+
create(Class)
|
|
480
|
+
}
|
|
481
|
+
invariant forall(Class o: not empty(o.rel))
|
|
482
|
+
ADSL
|
|
483
|
+
end
|
|
484
|
+
|
|
485
|
+
def test__delete_removes_all_refs
|
|
486
|
+
adsl_assert :correct, <<-ADSL
|
|
487
|
+
class Class { 0+ Class rel }
|
|
488
|
+
action blah() {
|
|
489
|
+
delete allof(Class)
|
|
490
|
+
a = create(Class)
|
|
491
|
+
b = create(Class)
|
|
492
|
+
a.rel += b
|
|
493
|
+
delete a
|
|
494
|
+
}
|
|
495
|
+
invariant forall(Class a: empty(a.rel))
|
|
496
|
+
ADSL
|
|
497
|
+
adsl_assert :incorrect, <<-ADSL
|
|
498
|
+
class Class { 0+ Class rel }
|
|
499
|
+
action blah() {
|
|
500
|
+
delete allof(Class)
|
|
501
|
+
a = create(Class)
|
|
502
|
+
b = create(Class)
|
|
503
|
+
a.rel += b
|
|
504
|
+
delete a
|
|
505
|
+
}
|
|
506
|
+
invariant !forall(Class a: empty(a.rel))
|
|
507
|
+
ADSL
|
|
508
|
+
end
|
|
509
|
+
|
|
510
|
+
def test__delete_ref
|
|
511
|
+
adsl_assert :correct, <<-ADSL
|
|
512
|
+
class Class { 0+ Class rel }
|
|
513
|
+
action blah() {
|
|
514
|
+
allof(Class).rel -= allof(Class)
|
|
515
|
+
}
|
|
516
|
+
invariant forall(Class a: empty(a.rel))
|
|
517
|
+
ADSL
|
|
518
|
+
adsl_assert :incorrect, <<-ADSL
|
|
519
|
+
class Class { 0+ Class rel }
|
|
520
|
+
action blah() {
|
|
521
|
+
allof(Class).rel -= allof(Class)
|
|
522
|
+
}
|
|
523
|
+
invariant exists(Class a: not empty(a.rel))
|
|
524
|
+
ADSL
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
def test_ref_cardinality__at_least_one
|
|
528
|
+
conjecture = <<-SPASS
|
|
529
|
+
forall( [o], implies(of_Class_type(o), exists([r], left_link_Class_rel(r, o))))
|
|
530
|
+
SPASS
|
|
531
|
+
adsl_assert :correct, <<-ADSL, :conjecture => conjecture
|
|
532
|
+
class Class { 1+ Class rel }
|
|
533
|
+
action blah() {}
|
|
534
|
+
ADSL
|
|
535
|
+
adsl_assert :incorrect, <<-ADSL, :conjecture => "not(#{conjecture})"
|
|
536
|
+
class Class { 1+ Class rel }
|
|
537
|
+
action blah() {}
|
|
538
|
+
ADSL
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
def test_ref_cardinality__at_most_one
|
|
542
|
+
conjecture = <<-SPASS
|
|
543
|
+
exists( [o, r1, r2], and(of_Class_type(o), left_link_Class_rel(r1, o), left_link_Class_rel(r2, o), not(equal(r1, r2))))
|
|
544
|
+
SPASS
|
|
545
|
+
adsl_assert :correct, <<-ADSL, :conjecture => "not(#{conjecture})"
|
|
546
|
+
class Class { 0..1 Class rel }
|
|
547
|
+
action blah() {}
|
|
548
|
+
ADSL
|
|
549
|
+
adsl_assert :incorrect, <<-ADSL, :conjecture => conjecture
|
|
550
|
+
class Class { 0..1 Class rel }
|
|
551
|
+
action blah() {}
|
|
552
|
+
ADSL
|
|
553
|
+
end
|
|
554
|
+
|
|
555
|
+
def test__inverse_relations
|
|
556
|
+
adsl_assert :correct, <<-ADSL
|
|
557
|
+
class Class1 { 1 Class2 rel }
|
|
558
|
+
class Class2 { 1 Class1 rel inverseof rel }
|
|
559
|
+
action blah() {}
|
|
560
|
+
invariant forall(Class1 a: a == a.rel.rel)
|
|
561
|
+
ADSL
|
|
562
|
+
end
|
|
563
|
+
end
|