Class: TheoryDependent

Inherits:
Object show all
Includes:
TheoryComponent
Defined in:
lib/theory/TheoryDependent.rb

Overview

A theory dependent is the “if” part of a theory. It states what needs to be true for a theory to be valid. For example “if varA == 7”, would be a theory dependent.

Instance Attribute Summary collapse

Attributes included from TheoryComponent

#theory_component_id

Instance Method Summary collapse

Methods included from TheoryComponent

#accessors, #generate_theory_component_id, #statements_with_variable, #tokens

Methods included from ActsAsCode

#write_structure

Constructor Details

#initialize(statement, theory_component_id = nil) ⇒ TheoryDependent

Returns a new instance of TheoryDependent.

Parameters:

  • statement

    A theory statement e.g. StringToTheory.run(“if(var1.pass?(var2))nreturn truenend”)

Raises:

  • (StandardError)


13
14
15
16
17
18
# File 'lib/theory/TheoryDependent.rb', line 13

def initialize(statement,theory_component_id=nil)
  raise StandardError.new('Expecting open statement but was '+statement.class.to_s) unless statement.kind_of?(OpenStatement)
  @statement = statement
  @theory_component_id = theory_component_id unless theory_component_id.nil?
  generate_theory_component_id
end

Instance Attribute Details

#statementObject (readonly)

Returns the value of attribute statement.



8
9
10
# File 'lib/theory/TheoryDependent.rb', line 8

def statement
  @statement
end

Instance Method Details

#copyObject

Returns a deep copy of the theory dependent but with a unique object_ids, all the data should be identical.



32
33
34
# File 'lib/theory/TheoryDependent.rb', line 32

def copy
  return TheoryDependent.new(@statement.copy,@theory_component_id)
end

#describe(tab = 0) ⇒ Object

Returns an abstract description of the dependent



21
22
23
# File 'lib/theory/TheoryDependent.rb', line 21

def describe(tab=0)
  return @statement.describe(tab)
end

#map_to(mapping) ⇒ Object

Returns a new theory dependent with the theory variables replaced with the values in the mapping hash.



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/theory/TheoryDependent.rb', line 58

def map_to(mapping)

  # Duplicate the current statement before it is rewritten
  rewritten_statement = @statement.copy

  # Find all the containers that contain TheoryVariables
  # NOTE  The statement is put in an array because select all doesn't include the array itself
  containers = [rewritten_statement].select_all {|x| x.respond_to?(:has?)}
  theory_variable_containers = containers.select {|x| x.has? {|y| y.kind_of?(TheoryVariable)}}
  
  # Rewrite the statement replacing the values
  theory_variable_containers.each do |z|
    z.replace_theory_variables!(mapping)
  end     
  
  return TheoryDependent.new(rewritten_statement,@theory_component_id)
end

#rewrite_permutations(realisable_variables) ⇒ Object

Returns an array of theory statements that realise this dependency using the passed variables.

en.wikipedia.org/wiki/Combination chriscontinanza.com/2010/10/29/Array.html

5! FACTORIAL

Raises:

  • (StandardError)


119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/theory/TheoryDependent.rb', line 119

def rewrite_permutations(realisable_variables)
  # TODO  Need to include a combination size check here - incase it is going to get insane
  raise StandardError.new('Currently requires at least one theory variable') if theory_variables.length == 0
  
  # Create an array of all the possible permutations that could replace this depenents' theory variables
  arrangements = realisable_variables.permutation(theory_variables.length).to_a

  # Construct a new theory dependent that use realisable variables inplace of 
  # the theory variables
  realisable_theory_dependents = []
  arrangements.each do |x|
      realisable_theory_dependents.push(self.copy.rewrite_with(x))
  end
  return realisable_theory_dependents
end

#rewrite_with(replacement_variables) ⇒ Object

Returns a duplicate theory dependent but with the theory variables replaced with those supplied.

Raises:

  • (StandardError)


79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/theory/TheoryDependent.rb', line 79

def rewrite_with(replacement_variables)
  raise StandardError.new("This theory dependent has #{theory_variables.length} not #{replacement_variables.length}") if replacement_variables.length != theory_variables.length
  rewritten_statement = @statement.copy

  # TODO  I think as well as copy I should have a rewrite_where(['var1'=>replacement_variables[0])
  
  # Find all the containers that contain TheoryVariables
  containers = [rewritten_statement].select_all {|x| x.respond_to?(:has?)}
  theory_variable_containers = containers.select {|x| x.has? {|y| y.kind_of?(TheoryVariable)}}

  # Collect all uniq variables
  # TODO  Check that only uniq variables are caught
  uniq_variables = theory_variable_containers.inject([]) {|results,x| results + x.variables }
  
  # Check that all the variables in the theory dependent can be replaced
  unless replacement_variables.length == uniq_variables.length 
    raise StandardError.new('Mismatch in the number of variables to be replaced and the number supplied')
  end
  
  # Create a mapping from the existing variable to the replacement ones
  # TODo  I really should use the varible id or something as the key
  mapping = []
  replacement_variables.zip(uniq_variables) do |x,y|
    mapping.push({:before=>y,:after=>x})
  end
  theory_variable_containers.each do |z|
    replacements = mapping.select {|x| x[:before].theory_variable_id == z.subject.theory_variable_id}
    z.subject = replacements.first[:after]
  end   
  return rewritten_statement 

end

#same_structure?(structure) ⇒ Boolean

TODO The same code is used for both TheoryDependent and TheoryResult Returns true if supplied statement has the same structure as this theory dependent’s, it has the same structure if everything about the statement is the same except for the variables. This means that the map_to method could be used to make it write identically.

Returns:



49
50
51
52
53
# File 'lib/theory/TheoryDependent.rb', line 49

def same_structure?(structure)
    return false unless structure.tokens.length == @statement.tokens.length
    return false unless structure.write_structure == @statement.write_structure
    return true
end

#theory_variablesObject

Returns all the theory vairables in this theory dependent.



39
40
41
# File 'lib/theory/TheoryDependent.rb', line 39

def theory_variables
  return @statement.select_all {|x| x.kind_of?(TheoryVariable)}
end

#write(tab = 0) ⇒ Object



25
26
27
# File 'lib/theory/TheoryDependent.rb', line 25

def write(tab=0)
  return @statement.write(tab)
end