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.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -20
  3. data/README.md +14 -21
  4. data/bin/adsl-verify +8 -8
  5. data/lib/adsl.rb +3 -0
  6. data/lib/adsl/adsl.rb +3 -0
  7. data/lib/adsl/ds/data_store_spec.rb +339 -0
  8. data/lib/adsl/extract/instrumenter.rb +206 -0
  9. data/lib/adsl/extract/meta.rb +33 -0
  10. data/lib/adsl/extract/rails/action_block_builder.rb +233 -0
  11. data/lib/adsl/extract/rails/action_instrumenter.rb +400 -0
  12. data/lib/adsl/extract/rails/action_runner.rb +57 -0
  13. data/lib/adsl/extract/rails/active_record_metaclass_generator.rb +555 -0
  14. data/lib/adsl/extract/rails/callback_chain_simulator.rb +135 -0
  15. data/lib/adsl/extract/rails/invariant_extractor.rb +48 -0
  16. data/lib/adsl/extract/rails/invariant_instrumenter.rb +70 -0
  17. data/lib/adsl/extract/rails/other_meta.rb +57 -0
  18. data/lib/adsl/extract/rails/rails_extractor.rb +211 -0
  19. data/lib/adsl/extract/rails/rails_instrumentation_test_case.rb +34 -0
  20. data/lib/adsl/extract/rails/rails_special_gem_instrumentation.rb +120 -0
  21. data/lib/adsl/extract/rails/rails_test_helper.rb +140 -0
  22. data/lib/adsl/extract/sexp_utils.rb +54 -0
  23. data/lib/adsl/fol/first_order_logic.rb +261 -0
  24. data/lib/adsl/parser/adsl_parser.racc +159 -0
  25. data/lib/{parser → adsl/parser}/adsl_parser.rex +4 -4
  26. data/lib/{parser → adsl/parser}/adsl_parser.rex.rb +6 -6
  27. data/lib/adsl/parser/adsl_parser.tab.rb +1031 -0
  28. data/lib/adsl/parser/ast_nodes.rb +1410 -0
  29. data/lib/adsl/railtie.rb +67 -0
  30. data/lib/adsl/spass/bin.rb +230 -0
  31. data/lib/{spass → adsl/spass}/ruby_extensions.rb +0 -0
  32. data/lib/adsl/spass/spass_ds_extensions.rb +931 -0
  33. data/lib/adsl/spass/spass_translator.rb +393 -0
  34. data/lib/adsl/spass/util.rb +13 -0
  35. data/lib/adsl/util/csv_hash_formatter.rb +94 -0
  36. data/lib/adsl/util/general.rb +228 -0
  37. data/lib/adsl/util/test_helper.rb +71 -0
  38. data/lib/adsl/verification/formula_generators.rb +231 -0
  39. data/lib/adsl/verification/instrumentation_filter.rb +50 -0
  40. data/lib/adsl/verification/invariant.rb +19 -0
  41. data/lib/adsl/verification/rails_verification.rb +33 -0
  42. data/lib/adsl/verification/utils.rb +20 -0
  43. data/lib/adsl/verification/verification_case.rb +13 -0
  44. data/test/integration/rails/rails_branch_verification_test.rb +112 -0
  45. data/test/integration/rails/rails_verification_test.rb +253 -0
  46. data/test/integration/spass/basic_translation_test.rb +563 -0
  47. data/test/integration/spass/control_flow_translation_test.rb +421 -0
  48. data/test/unit/adsl/ds/data_store_spec_test.rb +54 -0
  49. data/test/unit/adsl/extract/instrumenter_test.rb +103 -0
  50. data/test/unit/adsl/extract/meta_test.rb +142 -0
  51. data/test/unit/adsl/extract/rails/action_block_builder_test.rb +178 -0
  52. data/test/unit/adsl/extract/rails/action_instrumenter_test.rb +68 -0
  53. data/test/unit/adsl/extract/rails/active_record_metaclass_generator_test.rb +336 -0
  54. data/test/unit/adsl/extract/rails/callback_chain_simulator_test.rb +76 -0
  55. data/test/unit/adsl/extract/rails/invariant_extractor_test.rb +92 -0
  56. data/test/unit/adsl/extract/rails/rails_extractor_test.rb +1380 -0
  57. data/test/unit/adsl/extract/rails/rails_test_helper_test.rb +25 -0
  58. data/test/unit/adsl/extract/sexp_utils_test.rb +100 -0
  59. data/test/unit/adsl/fol/first_order_logic_test.rb +227 -0
  60. data/test/unit/adsl/parser/action_parser_test.rb +1040 -0
  61. data/test/unit/adsl/parser/ast_nodes_test.rb +359 -0
  62. data/test/unit/adsl/parser/class_parser_test.rb +288 -0
  63. data/test/unit/adsl/parser/general_parser_test.rb +67 -0
  64. data/test/unit/adsl/parser/invariant_parser_test.rb +432 -0
  65. data/test/unit/adsl/parser/parser_util_test.rb +126 -0
  66. data/test/unit/adsl/spass/bin_test.rb +65 -0
  67. data/test/unit/adsl/spass/ruby_extensions_test.rb +39 -0
  68. data/test/unit/adsl/spass/spass_ds_extensions_test.rb +7 -0
  69. data/test/unit/adsl/spass/spass_translator_test.rb +342 -0
  70. data/test/unit/adsl/util/csv_hash_formatter_test.rb +68 -0
  71. data/test/unit/adsl/util/general_test.rb +303 -0
  72. data/test/unit/adsl/util/test_helper_test.rb +120 -0
  73. data/test/unit/adsl/verification/formula_generators_test.rb +200 -0
  74. data/test/unit/adsl/verification/instrumentation_filter_test.rb +39 -0
  75. data/test/unit/adsl/verification/utils_test.rb +39 -0
  76. data/test/unit/adsl/verification/verification_case_test.rb +8 -0
  77. metadata +229 -29
  78. data/lib/ds/data_store_spec.rb +0 -292
  79. data/lib/fol/first_order_logic.rb +0 -260
  80. data/lib/parser/adsl_ast.rb +0 -779
  81. data/lib/parser/adsl_parser.racc +0 -151
  82. data/lib/parser/adsl_parser.tab.rb +0 -976
  83. data/lib/parser/dsdl_parser.rex.rb +0 -196
  84. data/lib/parser/dsdl_parser.tab.rb +0 -976
  85. data/lib/spass/bin.rb +0 -164
  86. data/lib/spass/spass_ds_extensions.rb +0 -870
  87. data/lib/spass/spass_translator.rb +0 -388
  88. data/lib/spass/util.rb +0 -11
  89. data/lib/util/csv_hash_formatter.rb +0 -47
  90. data/lib/util/test_helper.rb +0 -33
  91. data/lib/util/util.rb +0 -114
@@ -0,0 +1,126 @@
1
+ require 'adsl/parser/adsl_parser.tab.rb'
2
+ require 'test/unit'
3
+ require 'pp'
4
+
5
+ module ADSL::Parser
6
+ class ParserUtilTest < Test::Unit::TestCase
7
+ include ADSL::Parser
8
+ include ADSL::DS
9
+
10
+ def test_context__var_read_events
11
+ context = ASTTypecheckResolveContext.new
12
+ context.classes['class1'] = [:class1, :class1]
13
+ context.actions['action1'] = [:action1, :action1]
14
+ context.relations['class1'] = {"relation1" => [:relation1, :relation1]}
15
+ context.push_frame
16
+ var = DSVariable.new :name => "varname", :type => :whatever
17
+ context.define_var var, :node
18
+
19
+ counter = 0
20
+
21
+ context.on_var_read do |name|
22
+ assert_equal "varname", name
23
+ counter += 1
24
+ end
25
+
26
+ context.lookup_var "varname"
27
+
28
+ assert_equal 1, counter
29
+
30
+ context.push_frame
31
+ context.on_var_read do |name|
32
+ assert_equal "varname", name
33
+ assert_equal counter, 1
34
+ counter += 1
35
+ end
36
+
37
+ context.lookup_var "varname"
38
+ assert_equal 3, counter
39
+
40
+ context.pop_frame
41
+
42
+ context.lookup_var "varname"
43
+ assert_equal 4, counter
44
+ end
45
+
46
+ def test_context__var_write_events
47
+ context = ASTTypecheckResolveContext.new
48
+ context.classes['class1'] = [:class1, :class1]
49
+ context.actions['action1'] = [:action1, :action1]
50
+ context.relations['class1'] = {"relation1" => [:relation1, :relation1]}
51
+ context.push_frame
52
+
53
+ counter = 0
54
+
55
+ context.on_var_write do |name|
56
+ assert_equal "varname", name
57
+ counter += 1
58
+ end
59
+
60
+ var = DSVariable.new :name => "varname", :type => :whatever
61
+ context.define_var var, :node
62
+
63
+ assert_equal 1, counter
64
+
65
+ context.push_frame
66
+ context.on_var_write do |name|
67
+ assert_equal "varname", name
68
+ assert_equal counter, 1
69
+ counter += 1
70
+ end
71
+
72
+ context.redefine_var var, :node
73
+ assert_equal 3, counter
74
+
75
+ context.pop_frame
76
+
77
+ context.redefine_var var, :node
78
+ assert_equal 4, counter
79
+ end
80
+
81
+ def test_context__clone
82
+ context = ASTTypecheckResolveContext.new
83
+ context.classes['class1'] = [:class1, :class1]
84
+ context.actions['action1'] = [:action1, :action1]
85
+ context.relations['class1'] = {"relation1" => [:relation1, :relation1]}
86
+ context.push_frame
87
+ var = DSVariable.new :name => "varname", :type => :whatever
88
+ context.define_var var, :node
89
+
90
+ context2 = context.clone
91
+
92
+ assert context != context2
93
+ assert_equal [:class1, :class1], context2.classes.values.first
94
+ assert_equal 1, context2.var_stack.length
95
+
96
+ context2.on_var_write do |name|
97
+ flunk
98
+ end
99
+ assert context.var_stack.last.var_write_listeners.empty?
100
+
101
+ context.define_var DSVariable.new(:name => 'other', :type => :whatever), :node2
102
+
103
+ assert_equal 1, context2.var_stack.count
104
+ assert_equal 1, context.var_stack.count
105
+ assert_equal 2, context.var_stack.first.length
106
+ assert_equal 1, context2.var_stack.first.length
107
+
108
+ written = false
109
+ context.on_var_write do |name|
110
+ assert_equal "varname", name
111
+ written = true
112
+ end
113
+ context.push_frame
114
+
115
+ assert_equal 1, context2.var_stack.count
116
+ assert_equal 2, context.var_stack.count
117
+
118
+ context.redefine_var var, :node
119
+ assert written
120
+ end
121
+
122
+ def test_var_writes_and_reads
123
+
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,65 @@
1
+ require 'adsl/spass/bin'
2
+ require 'test/unit'
3
+
4
+ class ADSL::Spass::SpassBinTest < Test::Unit::TestCase
5
+ include ADSL::Spass::Bin
6
+
7
+ def test_exec_spass__spass_on_path
8
+ assert_nothing_raised do
9
+ exec_spass(<<-SPASS)
10
+ begin_problem(ProveTrue).
11
+
12
+ list_of_descriptions.
13
+ name({* *}).
14
+ author({* *}).
15
+ status(unsatisfiable).
16
+ description({* *}).
17
+ end_of_list.
18
+
19
+ list_of_formulae(conjectures).
20
+ formula(true).
21
+ end_of_list.
22
+
23
+ end_problem.
24
+ SPASS
25
+ end
26
+ end
27
+
28
+ def test_exec_spass__returns_correct
29
+ assert_equal :correct, exec_spass(<<-SPASS)
30
+ begin_problem(ProveTrue).
31
+
32
+ list_of_descriptions.
33
+ name({* *}).
34
+ author({* *}).
35
+ status(unsatisfiable).
36
+ description({* *}).
37
+ end_of_list.
38
+
39
+ list_of_formulae(conjectures).
40
+ formula(true).
41
+ end_of_list.
42
+
43
+ end_problem.
44
+ SPASS
45
+ end
46
+
47
+ def test_exec_spass__returns_incorrect
48
+ assert_equal :incorrect, exec_spass(<<-SPASS)
49
+ begin_problem(ProveTrue).
50
+
51
+ list_of_descriptions.
52
+ name({* *}).
53
+ author({* *}).
54
+ status(unsatisfiable).
55
+ description({* *}).
56
+ end_of_list.
57
+
58
+ list_of_formulae(conjectures).
59
+ formula(false).
60
+ end_of_list.
61
+
62
+ end_problem.
63
+ SPASS
64
+ end
65
+ end
@@ -0,0 +1,39 @@
1
+ require 'test/unit'
2
+ require 'adsl/spass/ruby_extensions'
3
+
4
+ class ADSL::Spass::RubyExtensionsTest < Test::Unit::TestCase
5
+ def test_string__resolve_params_distinct_identifiers
6
+ a = "asd(${1}, ${2})"
7
+ assert_equal "asd(a, b)", a.resolve_params(:a, :b)
8
+ assert_raise ArgumentError do
9
+ a.resolve_params(:s)
10
+ end
11
+ assert_equal "asd(s, k)", a.resolve_params(:s, :k, :r)
12
+ end
13
+
14
+ def test_string__resolve_params_repeating_identifiers
15
+ a = "asd(${1}, ${2}): ${1}"
16
+ assert_equal "asd(a, b): a", a.resolve_params(:a, :b)
17
+ assert_raise ArgumentError do
18
+ a.resolve_params(:s)
19
+ end
20
+ assert_equal "asd(s, k): s", a.resolve_params(:s, :k, :r)
21
+ end
22
+
23
+ def test_symbol__to_spass_string
24
+ assert_nothing_raised do
25
+ :a.to_spass_string
26
+ end
27
+ assert_equal "a", :a.to_spass_string
28
+ assert_equal "kme", :kme.to_spass_string
29
+ end
30
+
31
+ def test_string__to_spass_string
32
+ assert_nothing_raised do
33
+ "a".to_spass_string
34
+ end
35
+ assert_equal "a", "a".to_spass_string
36
+ assert_equal "kme", "kme".to_spass_string
37
+ end
38
+ end
39
+
@@ -0,0 +1,7 @@
1
+ require 'adsl/spass/spass_ds_extensions'
2
+ require 'adsl/fol/first_order_logic'
3
+ require 'test/unit'
4
+ require 'pp'
5
+
6
+ class ADSL::Spass::SpassDSExtensionsTest < Test::Unit::TestCase
7
+ end
@@ -0,0 +1,342 @@
1
+ require 'adsl/spass/spass_translator'
2
+ require 'adsl/ds/data_store_spec'
3
+ require 'adsl/fol/first_order_logic'
4
+ require 'test/unit'
5
+ require 'pp'
6
+
7
+ class ADSL::Spass::SpassTranslatorTest < Test::Unit::TestCase
8
+
9
+ def test_predicate__index_to_string
10
+ p = ADSL::Spass::SpassTranslator::Predicate.new :pred_name, 2
11
+ assert_equal 'pred_name(a, b)', p[:a, :b]
12
+ assert_raise ArgumentError do
13
+ p[:a]
14
+ end
15
+ end
16
+
17
+ def test_translation__unique_predicate_names
18
+ t = ADSL::Spass::SpassTranslator::Translation.new
19
+ state1 = t.create_state :name
20
+ state2 = t.create_state :name
21
+ assert_equal "name", state1.name
22
+ assert_equal "name_2", state2.name
23
+ function1 = t.create_function :name, 1
24
+ function2 = t.create_function :name, 2
25
+ assert_equal "name_3", function1.name
26
+ assert_equal "name_4", function2.name
27
+ assert_equal "something_with_prefix", t.create_predicate("something_with_prefix", 2).name
28
+ assert_equal "prefix", t.create_predicate("prefix", 2).name
29
+ assert_equal "prefix_2_asd", t.create_predicate("prefix_2_asd", 2).name
30
+
31
+ (1..5).each do |i|
32
+ c = t.create_predicate "context_1", 1
33
+ assert_equal "context_#{i}", c.name
34
+ end
35
+ end
36
+
37
+ def test_translation__reserve_names
38
+ t = ADSL::Spass::SpassTranslator::Translation.new
39
+ t.reserve_names :o do |o|
40
+ assert_equal :o, o
41
+ end
42
+ t.reserve_names do |*a|
43
+ assert_equal 0, a.length
44
+ end
45
+ t.reserve_names [:a, :b, :c] do |*a|
46
+ assert_equal 1, a.length
47
+ assert_equal 3, a[0].length
48
+ end
49
+ t.reserve_names :o do |o1|
50
+ t.reserve_names :o, :a do |o2, a|
51
+ assert_equal :o, o1
52
+ assert_equal :o_2, o2
53
+ assert_equal :a, a
54
+ end
55
+ t.reserve_names [:o, :o], :o do |os, o4|
56
+ o2 = os[0]
57
+ o3 = os[1]
58
+ assert_equal :o, o1
59
+ assert_equal :o_2, o2
60
+ assert_equal :o_3, o3
61
+ assert_equal :o_4, o4
62
+ end
63
+ end
64
+ end
65
+
66
+ def test_translation__gen_unique_arg_formula__integer_args
67
+ t = ADSL::Spass::SpassTranslator::Translation.new
68
+ pred = ADSL::Spass::SpassTranslator::Predicate.new :name, 2
69
+
70
+ assert_equal ADSL::FOL::ForAll.new(:a1, :e2, :b1, ADSL::FOL::Implies.new(
71
+ ADSL::FOL::And.new(pred[:a1, :e2], pred[:b1, :e2]),
72
+ ADSL::FOL::Equal.new(:a1, :b1)
73
+ )).resolve_spass, t.gen_formula_for_unique_arg(pred, 0).resolve_spass
74
+
75
+ assert_equal ADSL::FOL::And.new(
76
+ ADSL::FOL::ForAll.new(:a1, :e2, :b1, ADSL::FOL::Implies.new(
77
+ ADSL::FOL::And.new(pred[:a1, :e2], pred[:b1, :e2]),
78
+ ADSL::FOL::Equal.new(:a1, :b1)
79
+ )),
80
+ ADSL::FOL::ForAll.new(:e1, :a2, :b2, ADSL::FOL::Implies.new(
81
+ ADSL::FOL::And.new(pred[:e1, :a2], pred[:e1, :b2]),
82
+ ADSL::FOL::Equal.new(:a2, :b2)
83
+ ))
84
+ ).resolve_spass, t.gen_formula_for_unique_arg(pred, 0, 1).resolve_spass
85
+ end
86
+
87
+ def test_translation__gen_unique_arg_formula__range_args
88
+ t = ADSL::Spass::SpassTranslator::Translation.new
89
+ pred = ADSL::Spass::SpassTranslator::Predicate.new :name, 3
90
+
91
+ [[(0..0)], [0, (1..0)]].each do |args|
92
+ assert_equal ADSL::FOL::ForAll.new(:a1, :e2, :e3, :b1, ADSL::FOL::Implies.new(
93
+ ADSL::FOL::And.new(pred[:a1, :e2, :e3], pred[:b1, :e2, :e3]),
94
+ ADSL::FOL::Equal.new(:a1, :b1)
95
+ )).resolve_spass, t.gen_formula_for_unique_arg(pred, *args).resolve_spass
96
+ end
97
+
98
+ assert_equal ADSL::FOL::And.new(
99
+ ADSL::FOL::ForAll.new(:a1, :e2, :e3, :b1, ADSL::FOL::Implies.new(
100
+ ADSL::FOL::And.new(pred[:a1, :e2, :e3], pred[:b1, :e2, :e3]),
101
+ ADSL::FOL::Equal.new(:a1, :b1)
102
+ )),
103
+ ADSL::FOL::ForAll.new(:e1, :a2, :e3, :b2, ADSL::FOL::Implies.new(
104
+ ADSL::FOL::And.new(pred[:e1, :a2, :e3], pred[:e1, :b2, :e3]),
105
+ ADSL::FOL::Equal.new(:a2, :b2)
106
+ ))
107
+ ).resolve_spass, t.gen_formula_for_unique_arg(pred, 0, (1..1)).resolve_spass
108
+
109
+ assert_equal ADSL::FOL::ForAll.new(:a1, :a2, :e3, :b1, :b2, ADSL::FOL::Implies.new(
110
+ ADSL::FOL::And.new(pred[:a1, :a2, :e3], pred[:b1, :b2, :e3]),
111
+ ADSL::FOL::PairwiseEqual.new([:a1, :a2], [:b1, :b2])
112
+ )).resolve_spass, t.gen_formula_for_unique_arg(pred, (0..1)).resolve_spass
113
+
114
+ t.push_formula_frame
115
+ assert_equal 'true', t.gen_formula_for_unique_arg(pred, (1..0)).resolve_spass
116
+ assert t.pop_formula_frame.empty?
117
+ end
118
+
119
+ def test_context__names_of_context_related_stuff
120
+ t = ADSL::Spass::SpassTranslator::Translation.new
121
+ c1 = ADSL::Spass::SpassTranslator::FlatContext.new t, 'a', t.context
122
+ c1sub = ADSL::Spass::SpassTranslator::ChainedContext.new t, 'a', c1
123
+ c2 = ADSL::Spass::SpassTranslator::FlatContext.new t, 'a', t.context
124
+
125
+ assert_equal "true", t.context.type_pred(:a)
126
+ assert_equal "a(a)", c1.type_pred(:a)
127
+ assert_equal "a_2(p, a)", c1sub.type_pred(:p, :a)
128
+ assert_equal "a_3(a)", c2.type_pred(:a)
129
+ assert_equal "a_2_before(p, a, b)", c1sub.before_pred[:p, :a, :b]
130
+ end
131
+
132
+ def test_context__p_names
133
+ t = ADSL::Spass::SpassTranslator::Translation.new
134
+ assert_equal [], t.context.p_names
135
+
136
+ c = ADSL::Spass::SpassTranslator::FlatContext.new t, 'a', t.context
137
+ assert_equal [:p1], c.p_names
138
+
139
+ c2 = ADSL::Spass::SpassTranslator::FlatContext.new t, 'a', c
140
+ assert_equal [:p1, :p2], c2.p_names
141
+ assert_equal [:p1], c2.p_names(1)
142
+ assert_equal [:p1, :p2, :p3], c.p_names(3)
143
+ end
144
+
145
+ def test_context_common__get_common_level
146
+ t = ADSL::Spass::SpassTranslator::Translation.new
147
+ root_c = t.context
148
+ c1 = ADSL::Spass::SpassTranslator::FlatContext.new t, 'a', t.context
149
+ c1_sub = ADSL::Spass::SpassTranslator::FlatContext.new t, 'a', c1
150
+ c1_sub2 = ADSL::Spass::SpassTranslator::ChainedContext.new t, 'a', c1
151
+ c2 = ADSL::Spass::SpassTranslator::ChainedContext.new t, 'a', t.context
152
+
153
+ assert_equal root_c, ADSL::Spass::SpassTranslator::ContextCommon.get_common_context(root_c, root_c)
154
+ assert_equal root_c, ADSL::Spass::SpassTranslator::ContextCommon.get_common_context(root_c, c1)
155
+ assert_equal root_c, ADSL::Spass::SpassTranslator::ContextCommon.get_common_context(root_c, c1_sub)
156
+ assert_equal c1, ADSL::Spass::SpassTranslator::ContextCommon.get_common_context(c1, c1)
157
+ assert_equal c1, ADSL::Spass::SpassTranslator::ContextCommon.get_common_context(c1_sub, c1)
158
+ assert_equal c1, ADSL::Spass::SpassTranslator::ContextCommon.get_common_context(c1_sub, c1_sub2)
159
+ assert_equal root_c, ADSL::Spass::SpassTranslator::ContextCommon.get_common_context(c1, c2)
160
+ end
161
+
162
+ def test_context__order_in_root_context
163
+ # supposed to emulate two statements in the same for loop
164
+ t = ADSL::Spass::SpassTranslator::Translation.new
165
+ context = t.context
166
+
167
+ assert_equal "true", context.before(context, :c, :temp, true).resolve_spass
168
+ assert_equal "false", context.before(context, :c, :temp, false).resolve_spass
169
+ end
170
+
171
+ def test_context__order_same_lvl_chained
172
+ # supposed to emulate two statements in the same chained foreach loop
173
+ t = ADSL::Spass::SpassTranslator::Translation.new
174
+ c1 = ADSL::Spass::SpassTranslator::ChainedContext.new t, 'a', t.context
175
+
176
+ expected = ADSL::FOL::Implies.new(
177
+ ADSL::FOL::And.new(
178
+ c1.type_pred('a'), c1.type_pred('b')
179
+ ),
180
+ ADSL::FOL::And.new(
181
+ ADSL::FOL::Implies.new(c1.before_pred['a', 'b'], true),
182
+ ADSL::FOL::Implies.new(c1.before_pred['b', 'a'], false),
183
+ ADSL::FOL::Implies.new(
184
+ ADSL::FOL::Not.new(c1.before_pred['a', 'b'], c1.before_pred['b', 'a']),
185
+ false
186
+ )
187
+ )
188
+ )
189
+ assert_equal expected.resolve_spass, c1.before(c1, :a, :b, false).resolve_spass
190
+
191
+ expected = ADSL::FOL::Implies.new(
192
+ ADSL::FOL::And.new(
193
+ c1.type_pred('a'), c1.type_pred('b')
194
+ ),
195
+ ADSL::FOL::And.new(
196
+ ADSL::FOL::Implies.new(c1.before_pred['a', 'b'], true),
197
+ ADSL::FOL::Implies.new(c1.before_pred['b', 'a'], false),
198
+ ADSL::FOL::Implies.new(
199
+ ADSL::FOL::Not.new(c1.before_pred['a', 'b'], c1.before_pred['b', 'a']),
200
+ true
201
+ )
202
+ )
203
+ )
204
+ assert_equal expected.resolve_spass, c1.before(c1, :a, :b, true).resolve_spass
205
+ end
206
+
207
+ def test_context__order_same_lvl_flat
208
+ # supposed to emulate two statements in the same chained foreach loop
209
+ t = ADSL::Spass::SpassTranslator::Translation.new
210
+ c1 = ADSL::Spass::SpassTranslator::FlatContext.new t, 'a', t.context
211
+
212
+ expected = ADSL::FOL::Implies.new(
213
+ ADSL::FOL::And.new(
214
+ c1.type_pred('a'), c1.type_pred('b')
215
+ ),
216
+ ADSL::FOL::And.new(
217
+ ADSL::FOL::Implies.new(false, true),
218
+ ADSL::FOL::Implies.new(false, false),
219
+ ADSL::FOL::Implies.new(
220
+ ADSL::FOL::Not.new(false, false),
221
+ false
222
+ )
223
+ )
224
+ )
225
+ assert_equal expected.resolve_spass, c1.before(c1, :a, :b, false).resolve_spass
226
+
227
+ expected = ADSL::FOL::Implies.new(
228
+ ADSL::FOL::And.new(
229
+ c1.type_pred('a'), c1.type_pred('b')
230
+ ),
231
+ ADSL::FOL::And.new(
232
+ ADSL::FOL::Implies.new(false, true),
233
+ ADSL::FOL::Implies.new(false, false),
234
+ ADSL::FOL::Implies.new(
235
+ ADSL::FOL::Not.new(false, false),
236
+ true
237
+ )
238
+ )
239
+ )
240
+ assert_equal expected.resolve_spass, c1.before(c1, :a, :b, true).resolve_spass
241
+ end
242
+
243
+ def test_context__order_with_subcontext
244
+ # supposed to emulate a c1 statement followed by a c2 foreach with a stmt inside
245
+ t = ADSL::Spass::SpassTranslator::Translation.new
246
+ c1 = ADSL::Spass::SpassTranslator::FlatContext.new t, 'a', t.context
247
+ c2 = ADSL::Spass::SpassTranslator::ChainedContext.new t, 'a', c1
248
+
249
+ expected = ADSL::FOL::ForAll.new('parent_b1', ADSL::FOL::Implies.new(
250
+ ADSL::FOL::And.new(c1.type_pred('a'), c2.type_pred('parent_a1', 'b')),
251
+ true
252
+ ))
253
+ assert_equal expected.resolve_spass, c1.before(c2, :a, :b, true).resolve_spass
254
+
255
+ expected = ADSL::FOL::ForAll.new('parent_a1', ADSL::FOL::Implies.new(
256
+ ADSL::FOL::And.new(c2.type_pred('parent_a1', 'a'), c1.type_pred('b')),
257
+ false
258
+ ))
259
+ assert_equal expected.resolve_spass, c2.before(c1, :a, :b, false).resolve_spass
260
+ end
261
+
262
+ def test_context__listed_in_all_context
263
+ t = ADSL::Spass::SpassTranslator::Translation.new
264
+ c2 = t.create_context 'a', true, t.context
265
+ c3 = t.create_context 'a', true, c2
266
+ c4 = t.create_context 'a', true, c2
267
+ assert_equal 4, t.all_contexts.length
268
+ assert_equal Set[t.root_context, c2, c3, c4], Set[*t.all_contexts]
269
+ end
270
+
271
+ def test_context__statements_in_two_nested_fors
272
+ t = ADSL::Spass::SpassTranslator::Translation.new
273
+ outside_for_context = ADSL::Spass::SpassTranslator::ChainedContext.new t, 'a', t.context
274
+ inside_for_context = ADSL::Spass::SpassTranslator::ChainedContext.new t, 'a', outside_for_context
275
+ assert_not_equal inside_for_context.before_pred.name, outside_for_context.before_pred.name
276
+
277
+ expected = ADSL::FOL::ForAll.new('parent_a1', 'parent_b1', ADSL::FOL::Implies.new(
278
+ ADSL::FOL::And.new(
279
+ inside_for_context.type_pred('parent_a1', 'a'),
280
+ inside_for_context.type_pred('parent_b1', 'b')
281
+ ),
282
+ ADSL::FOL::And.new(
283
+ ADSL::FOL::Implies.new(outside_for_context.before_pred['parent_a1', 'parent_b1'], true),
284
+ ADSL::FOL::Implies.new(outside_for_context.before_pred['parent_b1', 'parent_a1'], false),
285
+ ADSL::FOL::Implies.new(
286
+ ADSL::FOL::Not.new(
287
+ outside_for_context.before_pred['parent_a1', 'parent_b1'],
288
+ outside_for_context.before_pred['parent_b1', 'parent_a1']
289
+ ),
290
+ ADSL::FOL::And.new(
291
+ ADSL::FOL::Implies.new(inside_for_context.before_pred['parent_a1', 'a', 'b'], true),
292
+ ADSL::FOL::Implies.new(inside_for_context.before_pred['parent_a1', 'b', 'a'], false),
293
+ ADSL::FOL::Implies.new(
294
+ ADSL::FOL::Not.new(
295
+ inside_for_context.before_pred['parent_a1', 'a', 'b'],
296
+ inside_for_context.before_pred['parent_a1', 'b', 'a']
297
+ ),
298
+ true
299
+ )
300
+ )
301
+ )
302
+ )
303
+ ))
304
+ assert_equal expected.resolve_spass, inside_for_context.before(inside_for_context, :a, :b, true).resolve_spass
305
+ end
306
+
307
+ def test_translation__pre_post_create_objs
308
+ translation = ADSL::Spass::SpassTranslator::Translation.new
309
+ a_klass = ADSL::DS::DSClass.new(:name => "a", :parent => nil, :relations => [])
310
+ a_stmt = ADSL::DS::DSCreateObj.new(:klass => a_klass)
311
+ b_klass = ADSL::DS::DSClass.new(:name => "b", :parent => nil, :relations => [])
312
+ b_stmt = ADSL::DS::DSCreateObj.new(:klass => b_klass)
313
+ block = ADSL::DS::DSBlock.new(:statements => [a_stmt, b_stmt])
314
+
315
+ translation.prev_state = translation.create_state :initial
316
+ block.prepare translation
317
+
318
+ assert_equal [a_klass, b_klass], translation.create_obj_stmts.keys.sort_by{ |a| a.name }
319
+ assert_equal [a_stmt], translation.create_obj_stmts[a_klass]
320
+ assert_equal [b_stmt], translation.create_obj_stmts[b_klass]
321
+ end
322
+
323
+ def test_spass_wrap
324
+ translation = ADSL::Spass::SpassTranslator::Translation.new
325
+ assert_equal "", translation.spass_wrap("blah\sblah", "")
326
+ assert_equal "blahasdblah", translation.spass_wrap("blah%sblah", "asd")
327
+ end
328
+
329
+ def test_spass_list_of
330
+ translation = ADSL::Spass::SpassTranslator::Translation.new
331
+ assert_equal "", translation.spass_list_of(:symbol, [])
332
+ assert_equal "", translation.spass_list_of(:symbol, [], [])
333
+ expected = <<-SPASS
334
+ list_of_symbol.
335
+ blah
336
+ kme
337
+ end_of_list.
338
+ SPASS
339
+ assert_equal expected.gsub(/^[ \t]+/, '').strip, translation.spass_list_of(:symbol, "blah", "kme").gsub(/^[ \t]+/, '')
340
+ end
341
+ end
342
+