Class: Rubylog::Variable

Inherits:
Object show all
Includes:
Goal
Defined in:
lib/rubylog/variable.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Goal

#solve, #true?

Constructor Details

#initialize(name = :"_#{object_id}") ⇒ Variable

Returns a new instance of Variable.



7
8
9
10
11
12
# File 'lib/rubylog/variable.rb', line 7

def initialize name = :"_#{object_id}"
  @name = name 
  @bound = false
  @dont_care = !!(name.to_s =~ /^(?:ANY|_)/i)
  @guards = []
end

Instance Attribute Details

#guardsObject

Returns the value of attribute guards.



173
174
175
# File 'lib/rubylog/variable.rb', line 173

def guards
  @guards
end

#nameObject (readonly)

data structure



6
7
8
# File 'lib/rubylog/variable.rb', line 6

def name
  @name
end

Instance Method Details

#==(other) ⇒ Object



29
30
31
# File 'lib/rubylog/variable.rb', line 29

def == other
  Variable === other and @name == other.name
end

#[](*guards) ⇒ Object

guards



168
169
170
171
# File 'lib/rubylog/variable.rb', line 168

def [] *guards
  @guards += guards
  self
end

#bound?Boolean

Returns:

  • (Boolean)


14
15
16
# File 'lib/rubylog/variable.rb', line 14

def bound?
  @bound
end

#dont_care?Boolean

Returns:

  • (Boolean)


43
44
45
# File 'lib/rubylog/variable.rb', line 43

def dont_care? 
  @dont_care
end

#eql?(other) ⇒ Boolean

Returns:

  • (Boolean)


33
34
35
# File 'lib/rubylog/variable.rb', line 33

def eql? other
  Variable === other and @name == other.name
end

#inspectObject



18
19
20
21
22
23
24
25
26
# File 'lib/rubylog/variable.rb', line 18

def inspect
  return "#{@name}=#{@value.inspect}" if @bound

  if @guards.empty?
    @name.to_s
  else
    "#{@name}#{@guards.inspect}"
  end
end

#proveObject



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/rubylog/variable.rb', line 120

def prove
  v = rubylog_dereference
  raise Rubylog::InstantiationError.new(self) if v.is_a? Rubylog::Variable

  # match variables if not matched
  unless v.rubylog_variables
    v = v.rubylog_match_variables
  end

  caught_cut = false

  catch :rubylog_cut do
    v.prove do
      # intercept cuts that come from the yield
      catch :rubylog_no_cut do
        catch :rubylog_cut do
          yield
          throw :rubylog_no_cut
        end
        caught_cut = true
      end
      break if caught_cut
    end
  end

  # pass through cut if one was caught from yield
  throw :rubylog_cut if caught_cut
end

#rubylog_deep_dereferenceObject



109
110
111
112
113
114
115
# File 'lib/rubylog/variable.rb', line 109

def rubylog_deep_dereference
  if @bound
    @value.rubylog_deep_dereference
  else
    self
  end
end

#rubylog_dereferenceObject



101
102
103
104
105
106
107
# File 'lib/rubylog/variable.rb', line 101

def rubylog_dereference
  if @bound
    @value.rubylog_dereference
  else
    self
  end
end

#rubylog_unify(other) ⇒ Object

Unifies the receiver with another value.

First dereferences both the receiver and the other. If both dereferenced values are variables, unifies them with the other being bound to the receiver. If one of them is a variable, it gets bound to the other value. If none of them is a variable, they are checked for equality with eql?. Succeeds if other is the same object as the receiver.



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/rubylog/variable.rb', line 63

def rubylog_unify other
  # check if we are bound
  if @bound
    # if we are bound
    # proceed to our dereferenced value
    rubylog_dereference.rubylog_unify(other) do yield end
  else
    # if we are unbound
    
    # dereference the other
    other = other.rubylog_dereference

    # if the other is a variable
    if other.is_a? Rubylog::Variable
      # succeed if same object
      (yield; return) if self.equal? other

      # we union our guards with the other's
      other.append_guards guards do
        # and bind to the other
        bind_to other do
          yield
        end
      end
    else
      # if the other is a value
      # bind to it and 
      bind_to other do
        # check our guards
        if guards.all? {|g|g.rubylog_matches_as_guard? other}
          yield
        end
      end
    end
  end
end

#rubylog_variablesObject

rubylog_clone stays as is



51
52
53
# File 'lib/rubylog/variable.rb', line 51

def rubylog_variables
  [self]
end

#to_aObject Also known as: to_ary

Array splats



151
152
153
# File 'lib/rubylog/variable.rb', line 151

def to_a
  [Rubylog::DSL::ArraySplat.new(self)]
end

#to_sObject

String variables



157
158
159
160
161
162
163
164
165
# File 'lib/rubylog/variable.rb', line 157

def to_s
  if @guards.empty?
    "#{String::RUBYLOG_VAR_START}#{@name}[]#{String::RUBYLOG_VAR_END}"
  else
    String::RubylogStringVariableGuards << @guards
    guard_index = String::RubylogStringVariableGuards.length-1
    "#{String::RUBYLOG_VAR_START}#{@name}[#{guard_index}]#{String::RUBYLOG_VAR_END}"
  end
end

#valueObject



39
40
41
# File 'lib/rubylog/variable.rb', line 39

def value
  @value if @bound
end