activefacts 0.8.16 → 0.8.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +15 -0
  2. data/Manifest.txt +10 -4
  3. data/bin/afgen +26 -20
  4. data/bin/cql +1 -1
  5. data/css/orm2.css +89 -9
  6. data/examples/CQL/CompanyDirectorEmployee.cql +4 -4
  7. data/examples/CQL/Genealogy.cql +5 -5
  8. data/examples/CQL/Metamodel.cql +121 -91
  9. data/examples/CQL/MonthInSeason.cql +2 -6
  10. data/examples/CQL/SeparateSubtype.cql +11 -9
  11. data/examples/CQL/ServiceDirector.cql +21 -33
  12. data/examples/CQL/Supervision.cql +0 -3
  13. data/examples/CQL/WindowInRoomInBldg.cql +10 -4
  14. data/examples/CQL/unit.cql +1 -1
  15. data/lib/activefacts.rb +1 -0
  16. data/lib/activefacts/cql/CQLParser.treetop +5 -1
  17. data/lib/activefacts/cql/Context.treetop +2 -7
  18. data/lib/activefacts/cql/Expressions.treetop +2 -2
  19. data/lib/activefacts/cql/FactTypes.treetop +37 -31
  20. data/lib/activefacts/cql/Language/English.treetop +21 -4
  21. data/lib/activefacts/cql/LexicalRules.treetop +59 -1
  22. data/lib/activefacts/cql/ObjectTypes.treetop +22 -12
  23. data/lib/activefacts/cql/Terms.treetop +13 -9
  24. data/lib/activefacts/cql/ValueTypes.treetop +30 -11
  25. data/lib/activefacts/cql/compiler.rb +34 -5
  26. data/lib/activefacts/cql/compiler/clause.rb +207 -116
  27. data/lib/activefacts/cql/compiler/constraint.rb +129 -105
  28. data/lib/activefacts/cql/compiler/entity_type.rb +49 -27
  29. data/lib/activefacts/cql/compiler/expression.rb +71 -42
  30. data/lib/activefacts/cql/compiler/fact.rb +70 -64
  31. data/lib/activefacts/cql/compiler/fact_type.rb +108 -57
  32. data/lib/activefacts/cql/compiler/query.rb +178 -0
  33. data/lib/activefacts/cql/compiler/shared.rb +13 -12
  34. data/lib/activefacts/cql/compiler/value_type.rb +10 -4
  35. data/lib/activefacts/cql/nodes.rb +1 -1
  36. data/lib/activefacts/cql/parser.rb +6 -2
  37. data/lib/activefacts/generate/absorption.rb +6 -3
  38. data/lib/activefacts/generate/cql.rb +140 -84
  39. data/lib/activefacts/generate/dm.rb +12 -6
  40. data/lib/activefacts/generate/help.rb +25 -6
  41. data/lib/activefacts/generate/helpers/oo.rb +195 -0
  42. data/lib/activefacts/generate/helpers/ordered.rb +589 -0
  43. data/lib/activefacts/generate/helpers/rails.rb +57 -0
  44. data/lib/activefacts/generate/html/glossary.rb +274 -54
  45. data/lib/activefacts/generate/json.rb +25 -22
  46. data/lib/activefacts/generate/null.rb +1 -0
  47. data/lib/activefacts/generate/rails/models.rb +244 -0
  48. data/lib/activefacts/generate/rails/schema.rb +185 -0
  49. data/lib/activefacts/generate/records.rb +1 -0
  50. data/lib/activefacts/generate/ruby.rb +51 -30
  51. data/lib/activefacts/generate/sql/mysql.rb +5 -3
  52. data/lib/activefacts/generate/sql/server.rb +8 -4
  53. data/lib/activefacts/generate/text.rb +1 -0
  54. data/lib/activefacts/generate/transform/surrogate.rb +209 -0
  55. data/lib/activefacts/generate/version.rb +1 -0
  56. data/lib/activefacts/input/orm.rb +234 -181
  57. data/lib/activefacts/mapping/rails.rb +122 -0
  58. data/lib/activefacts/persistence/columns.rb +34 -18
  59. data/lib/activefacts/persistence/foreignkey.rb +129 -71
  60. data/lib/activefacts/persistence/index.rb +42 -12
  61. data/lib/activefacts/persistence/reference.rb +37 -23
  62. data/lib/activefacts/persistence/tables.rb +53 -19
  63. data/lib/activefacts/registry.rb +11 -0
  64. data/lib/activefacts/support.rb +28 -10
  65. data/lib/activefacts/version.rb +1 -1
  66. data/lib/activefacts/vocabulary/extensions.rb +246 -117
  67. data/lib/activefacts/vocabulary/metamodel.rb +105 -65
  68. data/lib/activefacts/vocabulary/verbaliser.rb +226 -194
  69. data/spec/absorption_spec.rb +1 -0
  70. data/spec/cql/comparison_spec.rb +8 -8
  71. data/spec/cql/contractions_spec.rb +16 -43
  72. data/spec/cql/entity_type_spec.rb +2 -1
  73. data/spec/cql/expressions_spec.rb +2 -2
  74. data/spec/cql/fact_type_matching_spec.rb +4 -1
  75. data/spec/cql/parser/bad_literals_spec.rb +30 -30
  76. data/spec/cql/parser/entity_types_spec.rb +6 -6
  77. data/spec/cql/parser/expressions_spec.rb +25 -19
  78. data/spec/cql/samples_spec.rb +5 -4
  79. data/spec/cql_cql_spec.rb +2 -1
  80. data/spec/cql_dm_spec.rb +4 -0
  81. data/spec/cql_mysql_spec.rb +4 -0
  82. data/spec/cql_parse_spec.rb +2 -0
  83. data/spec/cql_ruby_spec.rb +4 -0
  84. data/spec/cql_sql_spec.rb +4 -0
  85. data/spec/cqldump_spec.rb +7 -4
  86. data/spec/helpers/parse_to_ast_matcher.rb +7 -3
  87. data/spec/helpers/test_parser.rb +2 -0
  88. data/spec/norma_cql_spec.rb +5 -2
  89. data/spec/norma_ruby_spec.rb +4 -1
  90. data/spec/norma_ruby_sql_spec.rb +4 -1
  91. data/spec/norma_sql_spec.rb +4 -1
  92. data/spec/norma_tables_spec.rb +2 -2
  93. data/spec/ruby_api_spec.rb +1 -1
  94. data/spec/spec_helper.rb +2 -0
  95. data/spec/transform_surrogate_spec.rb +59 -0
  96. metadata +70 -60
  97. data/TODO +0 -308
  98. data/lib/activefacts/cql/compiler/join.rb +0 -162
  99. data/lib/activefacts/generate/oo.rb +0 -176
  100. data/lib/activefacts/generate/ordered.rb +0 -602
@@ -4,7 +4,7 @@ module ActiveFacts
4
4
 
5
5
  # An Operation is a binary or ternary fact type involving an operator,
6
6
  # a result, and one or two operands.
7
- # Viewed as a result, it behaves like a VarRef with a nested Clause.
7
+ # Viewed as a result, it behaves like a Reference with a nested Clause.
8
8
  # Viewed as a fact type, it behaves like a Clause.
9
9
  #
10
10
  # The only exception here is an equality comparison, where it may
@@ -12,11 +12,11 @@ module ActiveFacts
12
12
  # the Operation is dropped from the clauses and is replaced by the
13
13
  # projected operand.
14
14
  #
15
- # Each operand may be a Literal, a VarRef, or another Operation,
16
- # so we need to recurse down the tree to build the join.
15
+ # Each operand may be a Literal, a Reference, or another Operation,
16
+ # so we need to recurse down the tree to build the query.
17
17
  #
18
18
  class Operation
19
- # VarRef (in)compatibility:
19
+ # Reference (in)compatibility:
20
20
  [ :term, :leading_adjective, :trailing_adjective, :role_name, :quantifier,
21
21
  :value_constraint, :embedded_presence_constraint, :literal
22
22
  ].each do |s|
@@ -28,15 +28,16 @@ module ActiveFacts
28
28
  def trailing_adjective; nil; end
29
29
  def value_constraint; nil; end
30
30
  def literal; nil; end
31
- attr_accessor :player # What ObjectType does the Variable denote
32
- attr_accessor :variable # What Variable for that ObjectType
31
+ def side_effects; nil; end
32
+ attr_accessor :player # What ObjectType does the Binding denote
33
+ attr_accessor :binding # What Binding for that ObjectType
33
34
  attr_accessor :clause # What clause does the result participate in?
34
35
  attr_accessor :role # Which Role of this ObjectType
35
36
  attr_accessor :role_ref # Which RoleRef to that Role
37
+ attr_accessor :certainty # nil, true, false -> maybe, definitely, not
36
38
  def nested_clauses; @nested_clauses ||= [self]; end
37
39
  def clause; self; end
38
40
  def objectification_of; @fact_type; end
39
-
40
41
  # Clause (in)compatibility:
41
42
  [ :phrases, :qualifiers, :context_note, :reading, :role_sequence, :fact
42
43
  ].each do |s|
@@ -45,7 +46,11 @@ module ActiveFacts
45
46
  end
46
47
  def conjunction; nil; end
47
48
  attr_reader :fact_type
48
- def objectified_as; self; end # The VarRef which objectified this fact type
49
+ def objectified_as; self; end # The Reference which objectified this fact type
50
+
51
+ def initialize
52
+ @certainty = true # Assume it's definite
53
+ end
49
54
 
50
55
  def operands context = nil
51
56
  raise "REVISIT: Implement operand enumeration in the operator subclass #{self.class.name}"
@@ -53,7 +58,7 @@ module ActiveFacts
53
58
 
54
59
  def identify_players_with_role_name context
55
60
  # Just recurse, there's no way (yet: REVISIT?) to add a role name to the result of an expression
56
- var_refs.each { |o|
61
+ refs.each { |o|
57
62
  o.identify_players_with_role_name(context)
58
63
  }
59
64
  # As yet, an operation cannot have a role name:
@@ -62,22 +67,22 @@ module ActiveFacts
62
67
 
63
68
  def identify_other_players context
64
69
  # Just recurse, there's no way (yet: REVISIT?) to add a role name to the result of an expression
65
- var_refs.each { |o|
70
+ refs.each { |o|
66
71
  o.identify_other_players(context)
67
72
  }
68
73
  identify_player context
69
74
  end
70
75
 
71
76
  def bind context
72
- var_refs.each do |o|
77
+ refs.each do |o|
73
78
  o.bind context
74
79
  end
75
80
  name = result_type_name(context)
76
81
  @player = result_value_type(context, name)
77
- key = "#{name} #{object_id}" # Every Operation result is a unique Variable
78
- @variable = (context.variables[key] ||= Variable.new(@player))
79
- @variable.refs << self
80
- @variable
82
+ key = "#{name} #{object_id}" # Every Operation result is a unique Binding
83
+ @binding = (context.bindings[key] ||= Binding.new(@player))
84
+ @binding.refs << self
85
+ @binding
81
86
  end
82
87
 
83
88
  def result_type_name(context)
@@ -87,7 +92,8 @@ module ActiveFacts
87
92
  def result_value_type(context, name)
88
93
  vocabulary = context.vocabulary
89
94
  constellation = vocabulary.constellation
90
- constellation.ValueType(vocabulary, name, :guid => :new)
95
+ vocabulary.valid_value_type_name(name) ||
96
+ constellation.ValueType(vocabulary, name, :guid => :new)
91
97
  end
92
98
 
93
99
  def is_naked_object_type
@@ -95,22 +101,25 @@ module ActiveFacts
95
101
  end
96
102
 
97
103
  def match_existing_fact_type context
98
- opnds = var_refs
99
- result_var_ref = VarRef.new(@variable.player.name)
100
- result_var_ref.player = @variable.player
101
- result_var_ref.variable = @variable
102
- @variable.refs << result_var_ref
104
+ opnds = refs
105
+ result_ref = Reference.new(@binding.player.name)
106
+ result_ref.player = @binding.player
107
+ result_ref.binding = @binding
108
+ @binding.refs << result_ref
103
109
  clause_ast = Clause.new(
104
- [result_var_ref, '='] +
110
+ [result_ref, '='] +
105
111
  (opnds.size > 1 ? [opnds[0]] : []) +
106
112
  [operator, opnds[-1]]
107
113
  )
108
114
 
109
115
  # REVISIT: All operands must be value-types or simply-identified Entity Types.
110
116
 
111
- # REVISIT: We should auto-create joins from Entity Types to an identifying ValueType
117
+ # REVISIT: We should auto-create steps from Entity Types to an identifying ValueType
112
118
  # REVISIT: We should traverse up the supertype of ValueTypes to find a DataType
113
119
  @fact_type = clause_ast.match_existing_fact_type(context, :exact_type => true)
120
+ if clause.certainty == false
121
+ raise "Negated fact types in expressions are not yet supported: #{clause.inspect}"
122
+ end
114
123
  return @fact_type if @fact_type
115
124
 
116
125
  @fact_type = clause_ast.make_fact_type context.vocabulary
@@ -121,6 +130,9 @@ module ActiveFacts
121
130
  opnds.each do |opnd|
122
131
  next unless opnd.is_a?(Operation)
123
132
  opnd.match_existing_fact_type context
133
+ if opnd.certainty == false
134
+ raise "Negated fact types in expressions are not yet supported: #{opnd.inspect}"
135
+ end
124
136
  end
125
137
  @fact_type
126
138
  end
@@ -142,16 +154,16 @@ module ActiveFacts
142
154
  class Comparison < Operation
143
155
  attr_accessor :operator, :e1, :e2, :qualifiers, :conjunction
144
156
 
145
- def initialize operator, e1, e2, qualifiers = []
146
- @operator, @e1, @e2, @qualifiers = operator, e1, e2, qualifiers
157
+ def initialize operator, e1, e2, certainty = true
158
+ @operator, @e1, @e2, @certainty, @qualifiers = operator, e1, e2, certainty, []
147
159
  end
148
160
 
149
- def var_refs
161
+ def refs
150
162
  [@e1, @e2]
151
163
  end
152
164
 
153
165
  def bind context
154
- var_refs.each do |o|
166
+ refs.each do |o|
155
167
  o.bind context
156
168
  end
157
169
 
@@ -160,10 +172,10 @@ module ActiveFacts
160
172
 
161
173
  name = 'Boolean'
162
174
  @player = result_value_type(context, name)
163
- key = "#{name} #{object_id}" # Every Comparison result is a unique Variable
164
- @variable = (context.variables[key] ||= Variable.new(@player))
165
- @variable.refs << self
166
- @variable
175
+ key = "#{name} #{object_id}" # Every Comparison result is a unique Binding
176
+ @binding = (context.bindings[key] ||= Binding.new(@player))
177
+ @binding.refs << self
178
+ @binding
167
179
  end
168
180
 
169
181
  def result_type_name(context)
@@ -180,7 +192,10 @@ module ActiveFacts
180
192
  raise "REVISIT: The player is the projected expression"
181
193
  end
182
194
  v = context.vocabulary
183
- @player = v.constellation.ValueType(v, 'Boolean', :guid => :new)
195
+ @boolean ||=
196
+ v.constellation.ValueType[[[v.name], 'Boolean']] ||
197
+ v.constellation.ValueType(v, 'Boolean', :guid => :new)
198
+ @player = @boolean
184
199
  end
185
200
  end
186
201
 
@@ -195,7 +210,21 @@ module ActiveFacts
195
210
  def inspect; to_s; end
196
211
 
197
212
  def to_s
198
- "compare#{operator}(#{e1.to_s} #{e2.to_s}#{@qualifiers.empty? ? '' : ', ['+@qualifiers*', '+']'})"
213
+ "compare#{
214
+ operator
215
+ }(#{
216
+ case @certainty
217
+ when nil; 'maybe '
218
+ when false; 'negated '
219
+ # else 'definitely '
220
+ end
221
+ }#{
222
+ e1.to_s
223
+ } #{
224
+ e2.to_s
225
+ }#{
226
+ @qualifiers.empty? ? '' : ', ['+@qualifiers*', '+']'
227
+ })"
199
228
  end
200
229
  end
201
230
 
@@ -205,7 +234,7 @@ module ActiveFacts
205
234
  @terms = terms
206
235
  end
207
236
 
208
- def var_refs
237
+ def refs
209
238
  @terms
210
239
  end
211
240
 
@@ -250,7 +279,7 @@ module ActiveFacts
250
279
  @factors = factors
251
280
  end
252
281
 
253
- def var_refs
282
+ def refs
254
283
  @factors
255
284
  end
256
285
 
@@ -298,7 +327,7 @@ module ActiveFacts
298
327
  '1/'
299
328
  end
300
329
 
301
- def var_refs
330
+ def refs
302
331
  [@divisor]
303
332
  end
304
333
 
@@ -396,20 +425,20 @@ module ActiveFacts
396
425
  when TrueClass, FalseClass; 'Boolean'
397
426
  end
398
427
  v = context.vocabulary
399
- @player = v.constellation.ValueType(v, player_name, :guid => :new)
428
+ @player = v.constellation.ValueType(v, player_name)
400
429
  end
401
430
  end
402
431
 
403
432
  def bind context
404
- @variable || begin
433
+ @binding || begin
405
434
  key = "#{@player.name} #{@literal}"
406
- @variable = (context.variables[key] ||= Variable.new(@player))
407
- @variable.refs << self
435
+ @binding = (context.bindings[key] ||= Binding.new(@player))
436
+ @binding.refs << self
408
437
  end
409
438
  end
410
439
 
411
- def variable
412
- @variable
440
+ def binding
441
+ @binding
413
442
  end
414
443
  end
415
444
 
@@ -9,12 +9,18 @@ module ActiveFacts
9
9
  end
10
10
 
11
11
  def compile
12
- @population = @constellation.Population(@vocabulary, @population_name, :guid => :new)
12
+ @population = @constellation.Population[[@vocabulary.identifying_role_values, @population_name]] ||
13
+ @constellation.Population(@vocabulary, @population_name, :guid => :new)
13
14
 
14
15
  @context = CompilationContext.new(@vocabulary)
15
16
  @context.bind @clauses
16
17
  @context.left_contraction_allowed = true
17
- @clauses.each{ |clause| clause.match_existing_fact_type @context }
18
+ @clauses.each do |clause|
19
+ ft = clause.match_existing_fact_type @context
20
+ if clause.certainty == false
21
+ raise "Negated fact #{clause.inspect} is not supported"
22
+ end
23
+ end
18
24
 
19
25
  # Figure out the simple existential facts and find fact types:
20
26
  @bound_facts = []
@@ -39,24 +45,24 @@ module ActiveFacts
39
45
  # Every bound word (term) in the phrases must have a literal
40
46
  # OR be bound to an entity type identified by the phrases
41
47
 
42
- # Any clause that has one variable and no other word is
48
+ # Any clause that has one binding and no other word is
43
49
  # either a value instance or a simply-identified entity.
44
- clause.var_refs.each do |var_ref|
45
- next unless l = var_ref.literal # No literal
46
- next if var_ref.variable.instance # Already bound
47
- player = var_ref.variable.player
48
- # raise "A literal may not be an objectification" if var_ref.role_ref.nested_clauses
49
- # raise "Not processing facts involving nested clauses yet" if var_ref.role_ref
50
+ clause.refs.each do |ref|
51
+ next unless l = ref.literal # No literal
52
+ next if ref.binding.instance # Already bound
53
+ player = ref.binding.player
54
+ # raise "A literal may not be an objectification" if ref.role_ref.nested_clauses
55
+ # raise "Not processing facts involving nested clauses yet" if ref.role_ref
50
56
  debug :instance, "Making #{player.class.basename} #{player.name} using #{l.inspect}" do
51
- var_ref.variable.instance = instance_identified_by_literal(player, l)
57
+ ref.binding.instance = instance_identified_by_literal(player, l)
52
58
  end
53
- var_ref
59
+ ref
54
60
  end
55
61
 
56
- if clause.phrases.size == 1 and (var_ref = clause.phrases[0]).is_a?(Compiler::VarRef)
57
- if var_ref.nested_clauses
62
+ if clause.phrases.size == 1 and (ref = clause.phrases[0]).is_a?(Compiler::Reference)
63
+ if ref.nested_clauses
58
64
  # Assign the objectified fact type as this clause's fact type?
59
- clause.fact_type = var_ref.player.fact_type
65
+ clause.fact_type = ref.player.fact_type
60
66
  clause
61
67
  else
62
68
  # This is an existential fact (like "Name 'foo'", or "Company 'Microsoft'")
@@ -64,7 +70,7 @@ module ActiveFacts
64
70
  end
65
71
  else
66
72
  raise "Fact Type not found: '#{clause.display}'" unless clause.fact_type
67
- # This instance will be associated with its variable by our caller
73
+ # This instance will be associated with its binding by our caller
68
74
  clause
69
75
  end
70
76
  end
@@ -76,26 +82,26 @@ module ActiveFacts
76
82
  return true if clause.fact
77
83
 
78
84
  # Find the roles of this clause that do not yet have an instance
79
- bare_roles = clause.var_refs.
80
- select do |var_ref|
81
- next false if var_ref.variable.instance
82
- next false if var_ref.literal and
83
- var_ref.variable.instance = instance_identified_by_literal(var_ref.variable.player, var_ref.literal)
85
+ bare_roles = clause.refs.
86
+ select do |ref|
87
+ next false if ref.binding.instance
88
+ next false if ref.literal and
89
+ ref.binding.instance = instance_identified_by_literal(ref.binding.player, ref.literal)
84
90
  true
85
91
  end
86
92
 
87
93
  debug :instance, "Considering '#{clause.display}' with "+
88
- (bare_roles.empty? ? "no bare roles" : "bare roles: #{bare_roles.map{|var_ref| var_ref.player.name}*", "}") do
94
+ (bare_roles.empty? ? "no bare roles" : "bare roles: #{bare_roles.map{|ref| ref.player.name}*", "}") do
89
95
 
90
96
  # If all the roles are in place, we can bind the rest of this clause:
91
97
  return true if bare_roles.size == 0 && bind_complete_fact(clause)
92
98
 
93
99
  progress = false
94
100
  if bare_roles.size == 1 &&
95
- (variable = bare_roles[0].variable) &&
96
- (et = variable.player).is_a?(ActiveFacts::Metamodel::EntityType)
101
+ (binding = bare_roles[0].binding) &&
102
+ (et = binding.player).is_a?(ActiveFacts::Metamodel::EntityType)
97
103
  if et.preferred_identifier.role_sequence.all_role_ref.detect{|rr| rr.role.fact_type == clause.fact_type} &&
98
- bind_entity_if_identifier_ready(clause, et, variable)
104
+ bind_entity_if_identifier_ready(clause, et, binding)
99
105
  progress = true
100
106
  end
101
107
  end
@@ -127,19 +133,19 @@ module ActiveFacts
127
133
  # Occasionally we need to search through all the clauses:
128
134
  def all_clauses
129
135
  @clauses.map do |clause|
130
- [clause] + clause.var_refs.map{|vr| vr.nested_clauses}
136
+ [clause] + clause.refs.map{|vr| vr.nested_clauses}
131
137
  end.flatten.compact
132
138
  end
133
139
 
134
140
  def bind_complete_fact clause
135
141
  return true unless clause.fact_type # An bare objectification
136
- debug :instance, "All variables in '#{clause.display}' contain instances; create the fact type"
137
- instances = clause.var_refs.map{|vr| vr.variable.instance}
142
+ debug :instance, "All bindings in '#{clause.display}' contain instances; create the fact type"
143
+ instances = clause.refs.map{|vr| vr.binding.instance}
138
144
  debug :instance, "Instances are #{instances.map{|i| "#{i.object_type.name} #{i.value.inspect}"}*", "}"
139
145
 
140
146
  if e = clause.fact_type.entity_type and
141
- clause.var_refs[0].variable.instance.object_type == e
142
- fact = clause.var_refs[0].variable.instance.fact
147
+ clause.refs[0].binding.instance.object_type == e
148
+ fact = clause.refs[0].binding.instance.fact
143
149
  else
144
150
  # Check that this fact doesn't already exist
145
151
  fact = clause.fact_type.all_fact.detect do |f|
@@ -169,7 +175,7 @@ module ActiveFacts
169
175
 
170
176
  if !fact.instance && clause.fact_type.entity_type
171
177
  # Objectified fact type; create the instance
172
- # Create the instance that objectifies this fact. We don't have the variable to assign it to though; that'll happen in our caller
178
+ # Create the instance that objectifies this fact. We don't have the binding to assign it to though; that'll happen in our caller
173
179
  debug :instance, "Objectifying fact as #{clause.fact_type.entity_type.name}"
174
180
  instance =
175
181
  @constellation.Instance(:new, :object_type => clause.fact_type.entity_type, :fact => fact, :population => @population)
@@ -179,8 +185,8 @@ module ActiveFacts
179
185
  if clause.fact and
180
186
  clause.objectified_as and
181
187
  instance = clause.fact.instance and
182
- instance.object_type == clause.objectified_as.variable.player
183
- clause.objectified_as.variable.instance = instance
188
+ instance.object_type == clause.objectified_as.binding.player
189
+ clause.objectified_as.binding.instance = instance
184
190
  end
185
191
 
186
192
  true
@@ -189,20 +195,20 @@ module ActiveFacts
189
195
  # If we have one bare role (no literal or instance) played by an entity type,
190
196
  # and the bound fact type participates in the identifier, we might now be able
191
197
  # to create the entity instance.
192
- def bind_entity_if_identifier_ready clause, entity_type, variable
198
+ def bind_entity_if_identifier_ready clause, entity_type, binding
193
199
  # Check this instance doesn't already exist already:
194
- identifying_variable = (clause.var_refs.map{|vr| vr.variable}-[variable])[0]
195
- return false unless identifying_variable # This happens when we have a bare objectification
196
- identifying_instance = identifying_variable.instance
200
+ identifying_binding = (clause.refs.map{|vr| vr.binding}-[binding])[0]
201
+ return false unless identifying_binding # This happens when we have a bare objectification
202
+ identifying_instance = identifying_binding.instance
197
203
  preferred_identifier = entity_type.preferred_identifier
198
204
 
199
- debug :instance, "This clause associates a new #{variable.player.name} with a #{identifying_variable.player.name}#{identifying_instance ? " which exists" : ""}"
205
+ debug :instance, "This clause associates a new #{binding.player.name} with a #{identifying_binding.player.name}#{identifying_instance ? " which exists" : ""}"
200
206
 
201
207
  identifying_role_ref = preferred_identifier.role_sequence.all_role_ref.detect { |rr|
202
- rr.role.fact_type == clause.fact_type && rr.role.object_type == identifying_variable.player
208
+ rr.role.fact_type == clause.fact_type && rr.role.object_type == identifying_binding.player
203
209
  }
204
210
  unless identifying_role_ref
205
- # This shold never happen; we already bound all var_refs
211
+ # This shold never happen; we already bound all refs
206
212
  debug :instance, "Failed to find a #{identifying_instance.object_type.name}"
207
213
  return false # We can't do this yet
208
214
  end
@@ -212,37 +218,37 @@ module ActiveFacts
212
218
  if role_value
213
219
  instance = (role_value.fact.all_role_value.to_a-[role_value])[0].instance
214
220
  debug :instance, "Found an existing instance (of #{instance.object_type.name}) from a previous definition"
215
- variable.instance = instance
221
+ binding.instance = instance
216
222
  return true # Done with this clause
217
223
  end
218
224
 
219
225
  pi_role_refs = preferred_identifier.role_sequence.all_role_ref
220
- # For each pi role, we have to find the fact clause, which contains the variable we need.
226
+ # For each pi role, we have to find the fact clause, which contains the binding we need.
221
227
  # Then we have to create an instance of each fact
222
228
  identifiers =
223
229
  pi_role_refs.map do |rr|
224
- # Find a clause that provides the identifying_var_ref for this player:
230
+ # Find a clause that provides the identifying_ref for this player:
225
231
  identifying_clause = all_clauses.detect do |clause|
226
232
  rr.role.fact_type == clause.fact_type &&
227
- clause.var_refs.detect{|vr| vr.variable == variable}
233
+ clause.refs.detect{|vr| vr.binding == binding}
228
234
  end
229
235
  return false unless identifying_clause
230
- identifying_var_ref = identifying_clause.var_refs.select{|var_ref| var_ref.variable != variable}[0]
231
- identifying_variable = identifying_var_ref ? identifying_var_ref.variable : nil
232
- identifying_instance = identifying_variable.instance
236
+ identifying_ref = identifying_clause.refs.select{|ref| ref.binding != binding}[0]
237
+ identifying_binding = identifying_ref ? identifying_ref.binding : nil
238
+ identifying_instance = identifying_binding.instance
233
239
 
234
- [rr, identifying_clause, identifying_variable, identifying_instance]
240
+ [rr, identifying_clause, identifying_binding, identifying_instance]
235
241
  end
236
242
  if identifiers.detect{ |i| !i[3] } # Not all required facts are bound yet
237
- debug :instance, "Can't go through with creating #{variable.player.name}; not all the identifying facts are in"
243
+ debug :instance, "Can't go through with creating #{binding.player.name}; not all the identifying facts are in"
238
244
  return false
239
245
  end
240
246
 
241
- debug :instance, "Going ahead with creating #{variable.player.name} using #{identifiers.size} roles" do
247
+ debug :instance, "Going ahead with creating #{binding.player.name} using #{identifiers.size} roles" do
242
248
  instance = @constellation.Instance(:new, :object_type => entity_type, :population => @population)
243
- variable.instance = instance
249
+ binding.instance = instance
244
250
  @bound_facts << instance
245
- identifiers.each do |rr, identifying_clause, identifying_variable, identifying_instance|
251
+ identifiers.each do |rr, identifying_clause, identifying_binding, identifying_instance|
246
252
  # This clause provides the identifying literal for the entity_type
247
253
  id_fact =
248
254
  identifying_clause.fact =
@@ -263,13 +269,13 @@ module ActiveFacts
263
269
  else
264
270
  debug :instance, "Making ValueType #{object_type.name} #{literal.inspect} #{@population.name.size>0 ? " in "+@population.name.inspect : ''}" do
265
271
 
266
- is_a_string = String === literal
272
+ is_literal_string = literal.literal.is_a?(String)
267
273
  instance = @constellation.Instance.detect do |key, i|
268
274
  # REVISIT: And same unit
269
275
  i.population == @population &&
270
276
  i.value &&
271
277
  i.value.literal == literal &&
272
- i.value.is_a_string == is_a_string
278
+ i.value.is_literal_string == is_literal_string
273
279
  end
274
280
  #instance = object_type.all_instance.detect { |instance|
275
281
  # instance.population == @population && instance.value == literal
@@ -279,7 +285,7 @@ module ActiveFacts
279
285
  instance = @constellation.Instance(:new)
280
286
  instance.object_type = object_type
281
287
  instance.population = @population
282
- instance.value = [literal.to_s, is_a_string, nil]
288
+ instance.value = [literal.to_s, is_literal_string, nil]
283
289
  @bound_facts << instance
284
290
  end
285
291
  instance
@@ -294,7 +300,7 @@ module ActiveFacts
294
300
  identifying_role_refs = object_type.preferred_identifier.role_sequence.all_role_ref
295
301
  raise "Single literal cannot satisfy multiple identifying roles for #{object_type.name}" if identifying_role_refs.size > 1
296
302
  role = identifying_role_refs.single.role
297
- # This instance has no variable; the variable is of the entity type not the identifying value type
303
+ # This instance has no binding; the binding is of the entity type not the identifying value type
298
304
  identifying_instance = instance_identified_by_literal role.object_type, literal
299
305
  existing_instance = nil
300
306
  instance_rv = identifying_instance.all_role_value.detect { |rv|
@@ -311,7 +317,7 @@ module ActiveFacts
311
317
  # This fact has no clause.
312
318
  fact = @constellation.Fact(:new, :fact_type => role.fact_type, :population => @population)
313
319
  @bound_facts << fact
314
- # This instance will be associated with its variable by our caller
320
+ # This instance will be associated with its binding by our caller
315
321
  instance = @constellation.Instance(:new, :object_type => object_type, :population => @population)
316
322
  @bound_facts << instance
317
323
  # The identifying fact type has two roles; create both role instances:
@@ -324,22 +330,22 @@ module ActiveFacts
324
330
 
325
331
  def complain_incomplete
326
332
  if @unbound_clauses.size > 0
327
- # Provide a readable description of the problem here, by showing each variable with no instance
328
- missing_variables = @unbound_clauses.
333
+ # Provide a readable description of the problem here, by showing each binding with no instance
334
+ missing_bindings = @unbound_clauses.
329
335
  map do |clause|
330
- clause.var_refs.
331
- select do |var_refs|
332
- !var_refs.variable.instance
336
+ clause.refs.
337
+ select do |refs|
338
+ !refs.binding.instance
333
339
  end.
334
- map do |var_ref|
335
- var_ref.variable
340
+ map do |ref|
341
+ ref.binding
336
342
  end
337
343
  end.
338
344
  flatten.
339
345
  uniq
340
346
 
341
347
  raise "Not enough facts are given to identify #{
342
- missing_variables.
348
+ missing_bindings.
343
349
  sort_by{|b| b.key}.
344
350
  map do |b|
345
351
  player_identifier =