Class: TheoryGenerator

Inherits:
Object show all
Defined in:
lib/core/TheoryGenerator.rb

Instance Method Summary collapse

Constructor Details

#initialize(filters = []) ⇒ TheoryGenerator

Returns a new instance of TheoryGenerator.



3
4
5
# File 'lib/core/TheoryGenerator.rb', line 3

def initialize(filters=[])
  @filters = filters
end

Instance Method Details

#action_works_with_runtime_method?(test_cases, runtime_method, action) ⇒ Boolean

Attempt to use the generated action with the runtime method to determine if it’s valid syntax.

Returns:



347
348
349
350
351
# File 'lib/core/TheoryGenerator.rb', line 347

def action_works_with_runtime_method?(test_cases,runtime_method,action)
  return TheoryChainValidator.new.add_statement_to_method(test_cases,runtime_method,action) ? true : false
rescue StandardError => e
  return false
end

#actions_validate_runtime_method?(runtime_method, test_cases, actions, mapping) ⇒ Boolean

Returns true if adding the supplied actions to the runtime method results in all the tests cases being met. This is useful to use before attempting to generate the theories to solve the test cases.

TODO I would rather the mapping was ChainMapping or ideally the mapping wasn’t passed

all, just have it as internal to the chain.

Returns:



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/core/TheoryGenerator.rb', line 63

def actions_validate_runtime_method?(runtime_method,test_cases,actions,mapping)
  
  # Declare the default finish for any problem
  head = Theory.new([],nil,[])
  tail = Parser.run("if(runtime_method.all_pass?(test_cases))\nreturn true\nend")
  
  # Create the chain 
  chain = Chain.new
  chain.form_chain(head,tail,mapping)
  
  # Add each of the actions to the chain
  actions.each do |action|
    chain.add_link(Theory.new([],action,[]))
  end
  
  # Implement the chain so that all variables are unified
  implementd_chain = chain.implement
  
end

#array_access(result, cauldron_method_call, mapping, theory_variable_ids, step, results = [], variable_history = []) ⇒ Object

TODO Why is results passed through if it is just overwritten?



625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
# File 'lib/core/TheoryGenerator.rb', line 625

def array_access(result,cauldron_method_call,mapping,theory_variable_ids,step,results=[],variable_history=[])
  
  results = []
  if cauldron_method_call == '[]'
    if result[:value].length > 4 then raise StandardError.new('Cauldron has not been tested with arrays larger that 4') end
      
    # Generate theory variables for each of the new accessors
    array_indexs = []    
    result[:value].length.times do |z|
      
      theory_id = theory_variable_ids.length
      
#        TODO Taking this complexity out for now.       
#        # Find pre-exisitng variables of the same value
#        # TODO    I should make sure I don't include unessary values here - I should check 
#        #         that the same array access has not already been included indirectly in
#        #         via the action. var2, var3 both refer to same fixnum for case 1
#        existing_variables = mapping.select{|key,value| value == z}
#        array_indexs += existing_variables.collect {|key,value|  TheoryVariable.new(key)}
      
      # Before adding a new variable - check that an existing one doesn't already exist
      
      #   * Generate the intrinsic statement for it
      new_written_intrinsic_statement = result[:intrinsic_statement].write+'['+z.to_s+']'
      # TODO  I might be able to use the results instead for the variable history now that I'm
      #       saving the intrinsic_statement
      if variable_history.any? { |x| new_written_intrinsic_statement == x[:intrinsic_statement].write }
        StandardLogger.instance.warning('Identical array access already exists '+new_written_intrinsic_statement)
        saved_variable = variable_history.find {|x| x[:intrinsic_statement].write == new_written_intrinsic_statement}
        
        #mapping[saved_variable[:global_variable_id]] = saved_variable[:variable_value].value
        mapping[saved_variable[:global_variable_id]] = z
        array_indexs << TheoryVariable.new(saved_variable[:global_variable_id])
      else
       
        mapping[theory_id] = z
        array_indexs << TheoryVariable.new(theory_id)
        theory_variable_ids << theory_variable_ids.length
      end
    end
    
    # Generate a statement for each of the calls
    array_indexs.each do |z|
      s = TheoryStatement.new(StringToTheory.run(result[:statement].write+'['+z.write+']'))
      v = obtain_value(s,mapping)
      var_ids = s.variables.collect {|a| a.theory_variable_id}
      var_values = var_ids.collect {|a| mapping[a]}
      results << {
        :value=>v,
        :statement=>s,
        :step=>step,
        :variable_values=>var_values,
        :intrinsic_statement=>convert_to_intrinsic_statement(s,mapping)
      }
 
      # Save the array history as well
      unless variable_history.any? {|x| x[:global_variable_id] == z.theory_variable_id}
        
        variable_history << {
          :intrinsic_statement=>convert_to_intrinsic_statement(s,mapping),
          :written_statement=>s.write,
          :variable_value=>var_values.last.to_intrinsic,
          :global_variable_id=>z.theory_variable_id
        }
        #raise StandardError.new('This array index has not been saved in the history '+z.theory_variable_id.to_s)
        
      end
      
    end
  end        
  return results
  
end

#covert_to_intrinsic_mapping(mapping) ⇒ Object



314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
# File 'lib/core/TheoryGenerator.rb', line 314

def covert_to_intrinsic_mapping(mapping)
  
  # Convert the mapping values into intrinsic values
  intrinsic_mapping = Mapping.new    
  test_cases_key = nil
  runtime_method_key = nil
  mapping.each do |key,value|
      
    # Convert fixnum into intrinisic fixnums
    if value.kind_of?(Fixnum)
      intrinsic_mapping[key] = IntrinsicLiteral.new(value)
      next
    end
    
    if value.kind_of?(RuntimeMethod)
      intrinsic_mapping[key] = Parser.run('runtime_method') 
      runtime_method_key = key
      next
    end
    
    if value.kind_of?(Array) && value.first.has_key?(:params)
      intrinsic_mapping[key] = Parser.run('test_cases')
      test_cases_key = key
      next
    end
    raise StandardError.new('Unknown value '+value.class.to_s)
  end
  return intrinsic_mapping
end

#extend_accessors(values, mapping, theory_variable_id, step, variable_history = []) ⇒ Object

Extends the provided accessors by another method call. For example if it is passed “test”, it would return ‘test’.length and ‘test’.lowercase etc.

Parameters:

  • initial_accessors

    An array of initial accessors containing the statement used to generate the value and the value itself. Literal Value>,:statement=><#Statement: A statement instance>

  • mapping

    The current mapping being used. This is extended when a new index is used. So if test_case is used, then 0 needs to have variable created for it and that added to the mapping.

  • variable_history (defaults to: [])

    This keeps track of each time a new variable is created via additional array access calls. This allows the structure of the theories to remain unified across the dependents and results.



436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
# File 'lib/core/TheoryGenerator.rb', line 436

def extend_accessors(values,mapping,theory_variable_id,step,variable_history=[])
  
  # Go through each of the values and get each of the cauldron method calls
  total_results = []
  values.each do |x|

    # Get the possible cauldron method calls
    results = []
    x[:value].cauldron_method_calls.each do |y|

        # Only get array access for values obtained in the last itteration
        if (step-1) == x[:step]
          results += params_output(x,y,mapping,theory_variable_id,step,values)
          results += array_access(x,y,mapping,theory_variable_id,step,values,variable_history)
        end
        
        # If the variable is new it should have all the paramters
        # If it isn't new it only needs the recent params

        # Only include parameters for recently created values
        if (step-1) == x[:step]
          results += use_method_call(x,y,mapping,theory_variable_id,step,values)
        else
          last_results = values.select {|z| z[:step] == (step-1)}
          results += use_method_call(x,y,mapping,theory_variable_id,step,last_results,true)
        end        
      
    end 
    total_results += results  
  end
  return total_results+values
end

#generate(test_cases, runtime_method, stage = 0) ⇒ Object

Returns an array of theories that add a variety of statements to the runtime method. The theories will be quite bloated since they’ll contain all the possible dependents and results.

Parameters:

  • values

    An array of literal values



120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/core/TheoryGenerator.rb', line 120

def generate(test_cases,runtime_method,stage=0)
 
  # 
  # TODO  Not keen on this parallel assignment (should really just 
  #       have a single instance containing the accessors and 
  #       mapping or have the mappig generated)
  accessors, mapping = generate_accessors_and_mapping(test_cases,runtime_method,4,stage)
  
  # Now generate some possible theories using these values
  return generate_theories(test_cases,runtime_method,accessors,mapping)
  
end

#generate_accessors_and_mapping(test_cases, runtime_method, itterations = 1, stage = 0) ⇒ Object

Returns an array of statements that use the values supplied but will return a value(including boolean).



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/core/TheoryGenerator.rb', line 136

def generate_accessors_and_mapping(test_cases,runtime_method,itterations=1,stage=0)
  
  # TODO  I'd like to drop this and just query the mapping instance
  theory_variable_ids = [0,1,2]

  # Create a theory variable for each of the values
  # runtime_method => 1
  # test_cases => 2    
  mapping = Mapping.new({
    1 => runtime_method.copy,
    2 => test_cases.copy
  })
  results = [
    {:value=>runtime_method.copy,:statement=>TheoryStatement.new(TheoryVariable.new(1)),:step=>0},
    {:value=>test_cases.copy,:statement=>TheoryStatement.new(TheoryVariable.new(2)),:step=>0}
  ]
  
  # Generate a number of values that can be obtained from the current runtime method and test cases
  itterations.times do |step|    
    results = extend_accessors(results,mapping,theory_variable_ids,(step+1))
  end
  return results, mapping
    
end

#generate_theories(test_cases, runtime_method, accessors, mapping) ⇒ Object



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/core/TheoryGenerator.rb', line 161

def generate_theories(test_cases,runtime_method,accessors,mapping)
  
  # Retreive theory dependets relating to the current method
  theory_dependents = get_theory_dependents(accessors.copy)
  
  # Retrieve possible statements to include in the theory
  theory_actions = get_theory_action(test_cases.copy,runtime_method.copy,accessors,mapping)
  
  # For each action retrieve the results of adding the statement
  theories = []
  theory_actions.each_with_index do |selected_action,i|
    
    # Add the statement to the runtime method and construct result theories based on it
    new_values = accessors.copy
    
    # Convert the mapping values into intrinsic values
    intrinsic_mapping = covert_to_intrinsic_mapping(mapping)      
    
    # Re-create the action with intrinsic variables
    implementated_action = selected_action.map_to(intrinsic_mapping)
    
    # Generate the runtime method that would be created by using that action
    modified_runtime_method = TheoryChainValidator.new.add_statement_to_method(
      test_cases.copy,
      runtime_method.copy,
      implementated_action
    )

    # TODO  I should maybe keep both runtime methods so the I can compare the runtime method's
    #       before and after.

    # Create a new mapping using the update runtime method
    new_mapping = mapping.copy
    new_mapping[1] = modified_runtime_method
    
    # Re-build the results but using the new value for the runtime method
    # re_evaluate_results
    # TODO  Using the same result statements is limiting  - there might be more calls available.
    new_results = re_evaluate_results(accessors,new_mapping)
    
    # Get the theory results for this modified runtime method
    theory_results = get_theory_results(new_results)

    # Create the complete theory
    theories << Theory.new(
      theory_dependents.copy,
      selected_action,
      theory_results,
      modified_runtime_method
    )
    
  end      
  
  return theories      
  
end

#generate_theories_for_actions(runtime_method, test_cases, actions) ⇒ Object

Returns a master and simplistic theory in conext of the supplied runtime method after each of the actions is added. So for each action there is new theory generated.

NOTE: This is the first time I’ve started to introduce this master/simply

theory paradigm.  The general rule I'm using is that the simple theory
only needs to be complex enough so it can indicate the order the actions
should be performed.

NOTE: The variables that each of theories use always refer to the same value. So

if var1 is the rutime method then var1 is the runtime method for all the theories.


52
53
54
# File 'lib/core/TheoryGenerator.rb', line 52

def generate_theories_for_actions(runtime_method,test_cases,actions)
  
end

#get_theory_action(test_cases, runtime_method, results, mapping) ⇒ Object



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
# File 'lib/core/TheoryGenerator.rb', line 218

def get_theory_action(test_cases,runtime_method,results,mapping)
  
  # Get possible statements ids
  statement_ids =  results.select {|x| x[:value].kind_of?(Fixnum)}
  
  actions = []
  
  # Add 'return <val>' statement
  results.each do |x|
    statement_ids.each do |y|
      # TODO  Shouldn't allow runtime methods to be included here
      actions << TheoryAction.new(
        TheoryStatement.new(StringToTheory.run("Statement.new(Return.new,#{x[:statement].write})")),
        StringToTheory.run(y[:statement].write)
      )
    end
  end
  
  # Exclude the runtime method from being included as a value (.write method becomes messy)
  # also excludes the orginal test_cases.
  valid_results = results.select do |x|
    
    # TODO  For some reason "x[:value].all? {|y| y.kind_of?(CTestCase)}" returns true for method Parameter (which is why this is here)
    next true if x[:value].kind_of?(MethodParameter)
    
    next false if x[:value].kind_of?(RuntimeMethod)
    
    # NOTE: This is only temporary - I don't really see anything wrong with nil
    next false if x[:value].kind_of?(NilClass)
    
    next false if x[:value].kind_of?(Array) && x[:value].all? {|y| y.kind_of?(CTestCase)}
    next true
  end
  
  (results-valid_results).each do |x|
    next if x[:value].nil?
  end
  
  # Generate "if(varA == varB) statements"
  value_pairs = valid_results.permutation(2)
  value_pairs.each do |x,y|
    statement_ids.each do |z|
      
      # if(x == y)
      # COMPROMISE - Only include statements with the same data type
      # TODO  They should be same type not identical so as long as the extend Array
      # TODO  I need to get the value of the runtime method parameter e.g. 'var2.params[var5]'
      if x[:value].class != MethodParameter and y[:value].class != MethodParameter
        next unless x[:value].class == y[:value].class
      end
      actions << TheoryAction.new(
        TheoryStatement.new(
          StringToTheory.run(
            "OpenStatement.new(Statement.new(If.new,Container.new(#{x[:statement].write},Equivalent.new,#{y[:statement].write})))"
          )
        ),
        StringToTheory.run(z[:statement].write)
      )  
    end
  end

  # TODO  I haven't allowed last_runtime_method to be used yet
  
  # ========================================================
  # Remove the actions that don't work
  # ========================================================
  # TODO  This duplicates the the "covert_to_intrinsic_mapping" method
  # Convert the mapping values into intrinsic values
  intrinsic_mapping = Mapping.new    
  test_cases_key = nil
  runtime_method_key = nil
  mapping.each do |key,value|
      
    # Convert fixnum into intrinisic fixnums
    if value.kind_of?(Fixnum)
      intrinsic_mapping[key] = IntrinsicLiteral.new(value)
      next
    end
    
  end
  intrinsic_mapping[1] = Parser.run('runtime_method')
  intrinsic_mapping[2] = Parser.run('test_cases') 
  
  # Attempt to add the statement to the actual runtime method
  valid_actions = []
  actions.each do |x|
    implementation = x.map_to(intrinsic_mapping)
    if action_works_with_runtime_method?(test_cases.copy,runtime_method.copy,implementation)
      valid_actions << x
    end
  end
  
  return valid_actions
  
end

#get_theory_dependents(results) ⇒ Object

Returns an array of theory dependents



355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
# File 'lib/core/TheoryGenerator.rb', line 355

def get_theory_dependents(results)
  
  # Create the theory dependents for all the values
  value_pairs = results.permutation(2)
  theory_dependents = []
  value_pairs.each do |x,y|
    if x[:value] == y[:value]
      theory_dependents << TheoryDependent.new(
        StringToTheory.run("if(#{x[:statement].write} == #{y[:statement].write})\nreturn true\nend")
      )
    else
      theory_dependents << TheoryDependent.new(
        StringToTheory.run("if((#{x[:statement].write} == #{y[:statement].write})==false)\nreturn true\nend")
      )
    end
  end    
  return theory_dependents
end

#get_theory_results(results) ⇒ Object



374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
# File 'lib/core/TheoryGenerator.rb', line 374

def get_theory_results(results)
  theory_results = []
  
  # Create the single statement theory results
  results.each do |x|
    if x[:value]
      theory_results << TheoryResult.new(
        StringToTheory.run("if(#{x[:statement].write})\nreturn true\nend")
      )
    elsif x[:value] == false
      theory_results << TheoryResult.new(
        StringToTheory.run("if((#{x[:statement].write})==false)\nreturn true\nend")
      )
    else
      StandardLogger.instance.error(x[:statement].write+' is '+x[:value].to_s)
    end
    # TODO  Should probably have else x[:value].nil? and StringToTheory.run("if((#{x[:statement].write}).nil?)\nreturn true\nend") 
  end
  
  # Create the theory dependents for all the values
  value_pairs = results.permutation(2)
  value_pairs.each do |x,y|
    if x[:value] == y[:value]
      theory_results << TheoryResult.new(
        StringToTheory.run("if(#{x[:statement].write} == #{y[:statement].write})\nreturn true\nend")
      )
    else
      theory_results << TheoryResult.new(
        StringToTheory.run("if((#{x[:statement].write} == #{y[:statement].write})==false)\nreturn true\nend")
      )
    end
  end    
  return theory_results    
  
end

#master_theories(chain, initial_runtime_method, test_cases) ⇒ Object

Returns an array of master theories(huge theories) generated using the runtime method at each stage of the chain.

Raises:

  • (StandardError)


10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/core/TheoryGenerator.rb', line 10

def master_theories(chain,initial_runtime_method,test_cases)
  raise StandardError.new('Currently only able to generate master theories for complete chains') unless chain.complete? 
  
  # Retrieve the full variable history for the chain - need to avoid duplicate variable creation especially if a variable 
  # only exists in the action.
  creation_history = chain.variables_creation(initial_runtime_method,test_cases)
  
  #   * Create the values array [{:value=>x,:statement=>:step=>}]
  master_theories = []
  chain.each_theory_progression(initial_runtime_method,test_cases) do |implemented_theory,theory|
        
    dependent_accessors = retrieve_accessors(implemented_theory.accessor_values[:before],creation_history)
    result_accessors = retrieve_accessors(implemented_theory.accessor_values[:after],creation_history)
    
    # Generate the dependents and results
    theory_dependents = get_theory_dependents(dependent_accessors.copy)[0..8]
    theory_results = get_theory_dependents(result_accessors.copy)[0..2]
    
    # Create the complete theory
    master_theories << Theory.new(
      theory_dependents.copy,
      theory.action.copy,
      theory_results
    )
    
  end
  return master_theories
  
end

#multiple_generate(runtime_method, test_cases, limit = 1) ⇒ Object

This generates an inital set of theories using the initial values. It then continues to generate additional theories after applying the action of the previously generated theories.



87
88
89
90
91
92
93
94
95
96
# File 'lib/core/TheoryGenerator.rb', line 87

def multiple_generate(runtime_method,test_cases,limit=1)
  theories = generate(test_cases,runtime_method,0)

  additional_theories = []
  theories.each_with_index do |x,i|
    additional_theories += recursive_generate(test_cases,x,1,(limit-1))
  end      
  return theories+additional_theories
  
end

#obtain_value(statement, mapping) ⇒ Object



699
700
701
702
703
704
705
706
707
708
709
# File 'lib/core/TheoryGenerator.rb', line 699

def obtain_value(statement,mapping)
  
  # Declare each of the theory variables with the correct value
  declaration = ''
  mapping.each do |key,value|
    declaration += 'var'+key.to_s+' = mapping['+key.to_s+']'+"\n"
  end
  eval(declaration)
  return eval(statement.write)
    
end

#params_output(result, cauldron_method_call, mapping, theory_variable_id, step, results = []) ⇒ Object



614
615
616
617
618
619
620
621
622
# File 'lib/core/TheoryGenerator.rb', line 614

def params_output(result,cauldron_method_call,mapping,theory_variable_id,step,results=[])
  results = []
  if cauldron_method_call.include?('[:params]') or cauldron_method_call.include?('[:output]')
    s = TheoryStatement.new(StringToTheory.run(result[:statement].write+cauldron_method_call))
    v = obtain_value(s,mapping)
    results << {:value=>v,:statement=>s,:step=>step}
  end    
  return results
end

#re_evaluate_results(results, mapping) ⇒ Object

Re-evaluate the values of each of the results using an updated runtime method instance.



413
414
415
416
417
418
419
420
# File 'lib/core/TheoryGenerator.rb', line 413

def re_evaluate_results(results,mapping)
  new_results = []
  results.each do |x|
    v = obtain_value(x[:statement],mapping)
    new_results << {:value=>v,:statement=>x[:statement],:step=>x[:step]}    
  end
  return new_results
end

#recursive_generate(test_cases, theory, stage, limit = 1, results = []) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/core/TheoryGenerator.rb', line 98

def recursive_generate(test_cases,theory,stage,limit=1,results=[])
  
  results << theory
  return results if limit == 0
  
  # TODO  It seems a bit wasteful to generate a whole new set of accessors for each
  #       new theory.  It should maybe just up accessors that include the runtime method.
  new_theories = generate(test_cases.copy,theory.example_runtime_method.copy,stage)
  
  new_theories.each do |x|
    recursive_generate(test_cases.copy,x,(stage+1),(limit-1),results)
  end
  return results

end

#use_method_call(result, cauldron_method_call, mapping, theory_variable_id, step, available_params, params_only = false) ⇒ Object



472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
# File 'lib/core/TheoryGenerator.rb', line 472

def use_method_call(result,cauldron_method_call,mapping,theory_variable_id,step,available_params,params_only=false)
  
  # Does it start with a '.'
  results = []
  if cauldron_method_call =~ /^\./
    
    # Does it require any parameters
    if ['.any?','.all_pass?','.pass?','.history2','.realise2','.kind_of?'].include?(cauldron_method_call)
      
      case cauldron_method_call
        when '.pass?'
          # Uses one parameter - a test case
          cauldron_test_cases = available_params.select {|x| x[:value].kind_of?(CTestCase)}
          cauldron_test_cases.each do |x|
            s = TheoryStatement.new(
              StringToTheory.run(result[:statement].write+cauldron_method_call+'('+x[:statement].write+')')
            )
            v = obtain_value(s,mapping)
            results << {:value=>v,:statement=>s,:step=>step}
          end
        when '.kind_of?'
          
          # TODO  Should probably include value class check here
          s = TheoryStatement.new(
            StringToTheory.run(result[:statement].write+cauldron_method_call+'(CTestCase)')
          )
          v = obtain_value(s,mapping)
          results << {:value=>v,:statement=>s,:step=>step}
          
          s2 = TheoryStatement.new(
            StringToTheory.run(result[:statement].write+cauldron_method_call+'(Fixnum)')
          )
          v2 = obtain_value(s,mapping)
          results << {:value=>v2,:statement=>s2,:step=>step}            
        when '.all_pass?'
          
          available_params.each do |x|
            if x[:value].kind_of?(Array) and x[:value].any? {|y| y.kind_of?(CTestCase)}
              s = TheoryStatement.new(
                StringToTheory.run(
                  result[:statement].write+cauldron_method_call+'('+x[:statement].write+')'
                )
              )
              v = obtain_value(s,mapping)
              results << {:value=>v,:statement=>s,:step=>step}    
            end
          end
          
        when '.history2'
          return []
          cauldron_arrays = available_params.select {|x| x[:value].kind_of?(Array)}
          cauldron_test_case_params = cauldron_arrays.select {|x| x[:statement].write.include?(':params')}
          cauldron_test_case_params.each do |x|
            s = TheoryStatement.new(
              StringToTheory.run(result[:statement].write+cauldron_method_call+'('+x[:statement].write+')')
            )
            v = obtain_value(s,mapping)
            results << {:value=>v,:statement=>s,:step=>step}
          end
        when '.realise2'
          cauldron_arrays = available_params.select {|x| x[:value].kind_of?(Array)}
          cauldron_test_case_params = cauldron_arrays.select {|x| x[:statement].write =~ /:params\]$/}
          cauldron_test_case_params.each do |x|
            s = TheoryStatement.new(
              StringToTheory.run(result[:statement].write+cauldron_method_call+'('+x[:statement].write+')')
            )
            v = obtain_value(s,mapping)
            results << {:value=>v,:statement=>s,:step=>step}
          end
        when '.any?'
          return []
          # if(var5.history2(var2[var3][:params]).any?{ |x| x['statement_id'] == var1.last.statement_id} )
          if result[:value].kind_of?(Array)
            available_params.each do |x|
              # TODO  Should probably only match values of the same type - I don't want 
              #       var1.any?{|x| x == var2.pass?(var1[var4])}
              
              # Only allow one block statement - 
              next if x[:statement].write.include?('{')
              
              # TODO  I should reduce the number of possible comparisons 
              #       (there is no point in comparing things will never be the same) 
              s = TheoryStatement.new(
                StringToTheory.run(
                  result[:statement].write+cauldron_method_call+'{|x| x == '+x[:statement].write+'}'
                )
              )
              v = obtain_value(s,mapping)    
              results << {:value=>v,:statement=>s,:step=>step}
            end
            
            # TODO  This is is a quick hack to get x[:statement] included - down the line it might
            #       require a separate extend_accessors call.
            if(result[:value].first.class==Step)
              result[:value].first.cauldron_method_calls.each do |x|
                
                available_params.each do |y|
                  
                  # Only allow one block statement - 
                  next if y[:statement].write.include?('{')                    
                  
                  s = TheoryStatement.new(
                    StringToTheory.run(
                      result[:statement].write+cauldron_method_call+'{|x| x'+x+' == '+y[:statement].write+'}'
                    )
                  )
                  v = obtain_value(s,mapping)                       
                  
                  results << {:value=>v,:statement=>s,:step=>step}
                  
                end
              end
            end
            
          else
            raise StandardError.new("Not setup for call '#{cauldron_method_call}'")
          end
      else
        raise StandardError.new("Not setup for call '#{cauldron_method_call}'")
      end
      
      # NOTE: These don't take parameters
    elsif ['.length','.last','.statement_id','.params','.value'].include?(cauldron_method_call)
      
      # Don't include this call if only parameter calls are being considered
      return [] if params_only
      
      s = TheoryStatement.new(StringToTheory.run(result[:statement].write+cauldron_method_call))
      v = obtain_value(s,mapping)
      results << {
        :value=>v,
        :statement=>s,
        :step=>step,
        :intrinsic_statement=>self.convert_to_intrinsic_statement(s,mapping)
      }
    else
      raise StandardError.new('Unknown method '+cauldron_method_call)
    end
  end    
  return results
end