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,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,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
|
+
|