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,228 @@
1
+ require 'set'
2
+ require 'open3'
3
+ require 'thread'
4
+ require 'active_support'
5
+
6
+ class String
7
+ def increment_suffix
8
+ suffix = scan(/_(\d+)$/).last
9
+ if suffix.nil?
10
+ return self + "_2"
11
+ else
12
+ suffix = suffix.first
13
+ return self[0, self.length - suffix.length] + (suffix.to_i + 1).to_s
14
+ end
15
+ end
16
+
17
+ # for lolz
18
+ def dyslexicize
19
+ gsub(/(\w)(\w+)(\w)/) { |match| ([$1] + $2.chars.to_a.shuffle + [$3]).join('') }
20
+ end
21
+
22
+ def adsl_indent
23
+ indented = " " + gsub("\n", "\n ")
24
+ (/ $/ =~ indented) ? indented[0..-3] : indented
25
+ end
26
+ end
27
+
28
+ class Time
29
+ def self.time_execution
30
+ pre = Time.now
31
+ yield
32
+ ((Time.now - pre)*1000).to_i
33
+ end
34
+ end
35
+
36
+ class Array
37
+ def worklist_each
38
+ changed = true
39
+ until empty? or not changed
40
+ changed = false
41
+ length.times do
42
+ task = self.shift
43
+ new_value = yield task
44
+ self << new_value if new_value
45
+ changed = true if task != new_value
46
+ end
47
+ end
48
+ end
49
+
50
+ def adsl_indent
51
+ join("").adsl_indent
52
+ end
53
+
54
+ def select_reject
55
+ arr1 = []
56
+ arr2 = []
57
+ self.each do |e|
58
+ if yield e
59
+ arr1 << e
60
+ else
61
+ arr2 << e
62
+ end
63
+ end
64
+ return arr1, arr2
65
+ end
66
+
67
+ def set_to(array)
68
+ self.clear
69
+ array.each{ |e| self << e }
70
+ self
71
+ end
72
+ end
73
+
74
+ class Symbol
75
+ def dup; self; end
76
+ end
77
+
78
+ class NilClass
79
+ def dup; self; end
80
+ end
81
+
82
+ class Fixnum
83
+ def dup; self; end
84
+ end
85
+
86
+ class TrueClass
87
+ def dup; self; end
88
+ end
89
+
90
+ class FalseClass
91
+ def dup; self; end
92
+ end
93
+
94
+ class Module
95
+ def parent_module
96
+ name.split('::')[0..-2].join('::').constantize
97
+ end
98
+
99
+ def lookup_const(const)
100
+ lookup_container = self
101
+ const.to_s.split('::').each do |portion|
102
+ portion = 'Object' if portion.empty?
103
+ return nil unless lookup_container.const_defined? portion
104
+ lookup_container = lookup_container.const_get portion
105
+ end
106
+ lookup_container
107
+ end
108
+
109
+ def lookup_or_create_module(name)
110
+ lookup_container = self
111
+ name.to_s.split('::').each do |portion|
112
+ portion = 'Object' if portion.empty?
113
+ unless lookup_container.const_defined? portion
114
+ new_module = Module.new
115
+ lookup_container.const_set portion, new_module
116
+ end
117
+ lookup_container = lookup_container.const_get portion
118
+ end
119
+ lookup_container
120
+ end
121
+
122
+ def lookup_or_create_class(name, superclass)
123
+ already_defined = lookup_const name
124
+ return already_defined unless already_defined.nil?
125
+
126
+ container_name = name.match(/^(.*)::\w+$/) ? $1 : 'Object'
127
+ container = lookup_or_create_module container_name
128
+ new_class = Class.new(superclass)
129
+ container.const_set name.to_s.split('::').last, new_class
130
+ new_class
131
+ end
132
+
133
+ def container_for(*fields, &block)
134
+ all_fields = Set.new(fields)
135
+ if respond_to? :container_for_fields
136
+ prev_fields = send :container_for_fields
137
+ all_fields.merge prev_fields
138
+ end
139
+ singleton_class.send :define_method, :container_for_fields, lambda{ all_fields }
140
+
141
+ attr_accessor *fields
142
+
143
+ send :define_method, :initialize do |*options|
144
+ options = options.empty? ? {} : options[0]
145
+ options ||= {}
146
+ options_trimmed = Hash[options]
147
+
148
+ all_fields.each do |field|
149
+ instance_variable_set "@#{field}".to_sym, options_trimmed.delete(field.to_sym)
150
+ end
151
+ if block
152
+ instance_eval &block
153
+ elsif not options_trimmed.empty?
154
+ raise ArgumentError, "Undefined fields mentioned in initializer of #{self.class}: #{options_trimmed.keys.map{ |key| ":#{key.to_s}"}.join(", ")}" + "\n[#{all_fields.to_a.join ' ' }]"
155
+ end
156
+ end
157
+
158
+ send :define_method, :recursively_gather do |method|
159
+ to_inspect = [self]
160
+ inspected = Set[]
161
+ while not to_inspect.empty?
162
+ elem = to_inspect.pop
163
+ inspected << elem
164
+ if elem.class.respond_to? :container_for_fields
165
+ elem.class.container_for_fields.each do |field|
166
+ field_val = elem.send(field)
167
+ next if field_val.nil?
168
+ [field_val].flatten.each do |subval|
169
+ to_inspect << subval unless inspected.include?(subval)
170
+ end
171
+ end
172
+ end
173
+ end
174
+ result = Set[]
175
+ inspected.each do |val|
176
+ result = result + [val.send(method)].flatten if val.class.method_defined?(method)
177
+ end
178
+ result.delete_if{ |a| a.nil? }.flatten
179
+ end
180
+ end
181
+ end
182
+
183
+ module Kernel
184
+ # returns stdout of the process that terminates first
185
+ # not completely thread safe; cannot be with 1.8.7
186
+ def process_race(*commands)
187
+ parent_thread = Thread.current
188
+ mutex = Mutex.new
189
+ children_threads = []
190
+ spawned_pids = []
191
+ result = nil
192
+ mutex.synchronize do
193
+ commands.each do |command|
194
+ children_threads << Thread.new do
195
+ begin
196
+ sleep 0.1
197
+ pipe = IO.popen command, 'r'
198
+ spawned_pids << pipe.pid
199
+ output = pipe.read
200
+ mutex.synchronize do
201
+ result = output if result.nil?
202
+ parent_thread.run
203
+ end
204
+ rescue => e
205
+ parent_thread.raise e unless e.message == 'die!'
206
+ end
207
+ end
208
+ end
209
+ end
210
+ Thread.stop
211
+ return result
212
+ ensure
213
+ children_threads.each do |child|
214
+ child.raise 'die!'
215
+ end
216
+ spawned_pids.each do |pid|
217
+ Process.kill 'HUP', pid
218
+ end
219
+ end
220
+
221
+ def until_no_change(object)
222
+ loop do
223
+ old_object = object
224
+ object = yield object
225
+ return object if old_object == object
226
+ end
227
+ end
228
+ end
@@ -0,0 +1,71 @@
1
+ require 'test/unit'
2
+ require 'adsl/parser/adsl_parser.tab'
3
+ require 'adsl/spass/bin'
4
+ require 'adsl/spass/spass_ds_extensions'
5
+ require 'adsl/spass/util'
6
+ require 'adsl/util/general'
7
+
8
+ class Test::Unit::TestCase
9
+ include ADSL::Spass::Bin
10
+ include ADSL::Spass::Util
11
+
12
+ SPASS_TIMEOUT = 5
13
+
14
+ def adsl_assert(expected_result, input, options={})
15
+ ds_spec = ADSL::Parser::ADSLParser.new.parse input
16
+ raise "Exactly one action required in ADSL" if ds_spec.actions.length != 1
17
+ action_name = ds_spec.actions.first.name
18
+ spass = ds_spec.translate_action(action_name)
19
+ spass = replace_conjecture spass, options[:conjecture] if options.include? :conjecture
20
+ result = exec_spass(spass, options[:timeout] || SPASS_TIMEOUT)
21
+ if result == :inconclusive
22
+ puts "inconclusive result on testcase #{self.class.name}.#{method_name}"
23
+ else
24
+ assert_equal expected_result, result
25
+ end
26
+ rescue Exception => e
27
+ puts spass unless spass.nil?
28
+ raise e
29
+ end
30
+
31
+ def spass_assert(expected_result, input, timeout = SPASS_TIMEOUT)
32
+ adsl_assert expected_result, input, :timeout => timeout
33
+ end
34
+
35
+ def unload_class(*classes)
36
+ classes.each do |klass_name|
37
+ const = self.class.lookup_const klass_name
38
+ next if const.nil?
39
+ const.parent_module.send :remove_const, const.name.split('::').last
40
+ end
41
+ end
42
+
43
+ def class_defined?(*classes)
44
+ classes.each do |klass_name|
45
+ return true unless self.class.lookup_const(klass_name).nil?
46
+ end
47
+ return false
48
+ end
49
+
50
+ def in_temp_file(content)
51
+ file = Tempfile.new('test_util')
52
+ file.write content
53
+ file.close
54
+ yield file.path
55
+ ensure
56
+ file.unlink unless file.nil?
57
+ end
58
+
59
+ def assert_set_equal(expected, actual, failure_msg = nil)
60
+ expected.each do |elem|
61
+ assert_block failure_msg || "Actual collection does not contain `#{elem}'" do
62
+ actual.include? elem
63
+ end
64
+ end
65
+ actual.each do |elem|
66
+ assert_block failure_msg || "Expected collection does not contain `#{elem}'" do
67
+ expected.include? elem
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,231 @@
1
+ require 'adsl/verification/utils'
2
+ require 'adsl/parser/ast_nodes'
3
+ require 'adsl/util/general'
4
+
5
+ module ADSL
6
+ module Verification
7
+
8
+ # forward declaration
9
+ class FormulaBuilder; end
10
+
11
+ module FormulaGenerators
12
+ include Utils
13
+ include ADSL::Parser
14
+
15
+ def in_formula_builder
16
+ formula_builder = nil
17
+ if self.is_a? ::ADSL::Verification::FormulaBuilder
18
+ formula_builder = self
19
+ else
20
+ formula_builder = ::ADSL::Verification::FormulaBuilder.new
21
+ formula_builder.adsl_stack << self.adsl_ast if self.respond_to? :adsl_ast
22
+ end
23
+ yield formula_builder
24
+ formula_builder
25
+ end
26
+
27
+ def handle_quantifier(quantifier, adsl_ast_node_klass, arg_types, block)
28
+ raise "A block needs to be passed to quantifiers" if block.nil?
29
+ raise "At least some variables need to be given to the block" if block.parameters.empty?
30
+ in_formula_builder do |fb|
31
+
32
+ param_types = {}
33
+ block.parameters.each do |param|
34
+ classname = infer_classname_from_varname param[1]
35
+ klass = Object.lookup_const classname
36
+ param_types[param[1].to_sym] = klass
37
+ end
38
+ arg_types.each do |explicit_name, explicit_type|
39
+ classname = classname_for_classname explicit_type
40
+ klass = Object.lookup_const classname
41
+ raise "Unknown class #{explicit_type} for parameter #{explicit_name}" if klass.nil?
42
+ param_types[explicit_name.to_sym] = klass
43
+ end
44
+
45
+ param_types.each do |name, klass|
46
+ raise "Unknown klass for variable `#{name}' in #{quantifier} quantifier" if klass.nil?
47
+ raise "Class #{klass.name} is not instrumented" unless klass.respond_to? :adsl_ast
48
+ end
49
+
50
+ vars_and_objsets = block.parameters.map{ |param|
51
+ [
52
+ t(param[1].to_s),
53
+ param_types[param[1].to_sym].all.adsl_ast
54
+ ]
55
+ }
56
+ subformula = block.(*block.parameters.map do |param|
57
+ param_types[param[1].to_sym].new :adsl_ast => ASTVariable.new(:var_name => t(param[1]))
58
+ end)
59
+ subformula = true if subformula.nil?
60
+ raise "Invalid formula returned by block in `#{quantifier}'" unless subformula.respond_to? :adsl_ast
61
+ fb.adsl_stack << adsl_ast_node_klass.new(:vars => vars_and_objsets, :subformula => subformula.adsl_ast)
62
+ end
63
+ end
64
+
65
+ def forall(arg_types = {}, &block)
66
+ handle_quantifier :forall, ASTForAll, arg_types, block
67
+ end
68
+
69
+ def exists(arg_types = {}, &block)
70
+ handle_quantifier :exists, ASTExists, arg_types, block
71
+ end
72
+
73
+ def not(param = nil)
74
+ in_formula_builder do |fb|
75
+ if param.nil?
76
+ fb.adsl_stack << :not
77
+ else
78
+ fb.adsl_stack << ASTNot.new(:subformula => param.adsl_ast)
79
+ end
80
+ end
81
+ end
82
+ alias_method :neg, :not
83
+
84
+ def true
85
+ in_formula_builder do |fb|
86
+ fb.adsl_stack << true.adsl_ast
87
+ end
88
+ end
89
+
90
+ def false
91
+ in_formula_builder do |fb|
92
+ fb.adsl_stack << false.adsl_ast
93
+ end
94
+ end
95
+
96
+ def [](formula)
97
+ in_formula_builder do |fb|
98
+ formula = formula.adsl_ast if formula.respond_to? :adsl_ast
99
+ fb.adsl_stack << formula
100
+ end
101
+ end
102
+
103
+ def binary_op_with_any_number_of_params(op, klass, params)
104
+ in_formula_builder do |fb|
105
+ if params.empty?
106
+ fb.adsl_stack << op
107
+ else
108
+ params.each do |param|
109
+ raise "Invalid formula `#{param}' in `#{op}' parameter list" unless param.respond_to? :adsl_ast
110
+ end
111
+ fb.adsl_stack << klass.new(:subformulae => params.map(&:adsl_ast))
112
+ end
113
+ end
114
+ end
115
+
116
+ def binary_op(op, klass, params)
117
+ raise "`#{op}' takes two parameters or none at all" unless params.empty? or params.length == 2
118
+ in_formula_builder do |fb|
119
+ if params.empty?
120
+ fb.adsl_stack << op
121
+ else
122
+ params.each do |param|
123
+ raise "Invalid formula `#{param}' in `#{op}' parameter list" unless param.respond_to? :adsl_ast
124
+ end
125
+ fb.adsl_stack << klass.new(:subformula1 => params.first.adsl_ast, :subformula2 => params.last.adsl_ast)
126
+ end
127
+ end
128
+ end
129
+
130
+ def and(*params)
131
+ binary_op_with_any_number_of_params :and, ASTAnd, params
132
+ end
133
+
134
+ def or(*params)
135
+ binary_op_with_any_number_of_params :or, ASTOr, params
136
+ end
137
+
138
+ def equiv(*params)
139
+ binary_op_with_any_number_of_params :equiv, ASTEquiv, params
140
+ end
141
+
142
+ def implies(*params)
143
+ binary_op :implies, ASTImplies, params
144
+ end
145
+ end
146
+
147
+ class FormulaBuilder
148
+ include FormulaGenerators
149
+
150
+ attr_reader :adsl_stack
151
+
152
+ def initialize(component = nil)
153
+ @adsl_stack = []
154
+ @adsl_stack << component unless component.nil?
155
+ end
156
+
157
+ def handle_unary_operator(elements, operator)
158
+ until (index = elements.find_index(operator)).nil?
159
+ raise "Unary operator `#{operator}' not prefix-called" if index == elements.length-1
160
+ arg = elements[index+1]
161
+ raise "`#{arg}', used by operator `#{operator}', is not a formula" unless arg.is_a? ASTNode
162
+ result = yield arg
163
+ elements.delete_at index
164
+ elements[index] = result
165
+ end
166
+ end
167
+
168
+ def handle_binary_operator(elements, operator)
169
+ until (index = elements.find_index(operator)).nil?
170
+ raise "Binary operator `#{operator}' not infix-called" if index == 0 or index == elements.length-1
171
+ args = [elements[index-1], elements[index+1]]
172
+ args.each do |arg|
173
+ raise "`#{arg}', used by operator `#{operator}', is not a formula" unless arg.is_a? ASTNode
174
+ end
175
+ result = yield *args
176
+ elements.delete_at index - 1
177
+ elements.delete_at index - 1
178
+ elements[index - 1] = result
179
+ end
180
+ end
181
+
182
+ def gather_adsl_asts
183
+ elements = @adsl_stack.clone
184
+ handle_unary_operator elements, :not do |formula|
185
+ ASTNot.new(:subformula => formula)
186
+ end
187
+ handle_binary_operator elements, :and do |formula1, formula2|
188
+ ASTAnd.new(:subformulae => [formula1, formula2])
189
+ end
190
+ handle_binary_operator elements, :or do |formula1, formula2|
191
+ ASTOr.new(:subformulae => [formula1, formula2])
192
+ end
193
+ handle_binary_operator elements, :implies do |formula1, formula2|
194
+ ASTImplies.new(:subformula1 => formula1, :subformula2 => formula2)
195
+ end
196
+ handle_binary_operator elements, :equiv do |formula1, formula2|
197
+ ASTEquiv.new(:subformula1 => formula1, :subformula2 => formula2)
198
+ end
199
+ elements
200
+ end
201
+
202
+ def adsl_ast
203
+ elements = gather_adsl_asts
204
+ if elements.length != 1
205
+ raise "Invalid formula/operator stack state [#{ elements.map{ |e| e.respond_to?(:to_adsl) ? e.to_adsl : e }.join(', ') }]"
206
+ end
207
+ elements.first
208
+ end
209
+ end
210
+ end
211
+ end
212
+
213
+ class TrueClass
214
+ include ADSL::Verification::FormulaGenerators
215
+
216
+ def adsl_ast
217
+ ASTBoolean.new(:bool_value => self)
218
+ end
219
+ end
220
+
221
+ class FalseClass
222
+ include ADSL::Verification::FormulaGenerators
223
+
224
+ def adsl_ast
225
+ ASTBoolean.new(:bool_value => self)
226
+ end
227
+ end
228
+
229
+ class ADSL::Parser::ASTNode
230
+ include ADSL::Verification::FormulaGenerators
231
+ end