activefacts 0.8.9 → 0.8.10

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 (120) hide show
  1. data/.gemtest +0 -0
  2. data/Manifest.txt +28 -33
  3. data/Rakefile +11 -12
  4. data/bin/cql +90 -46
  5. data/examples/CQL/Blog.cql +2 -1
  6. data/examples/CQL/CompanyDirectorEmployee.cql +2 -2
  7. data/examples/CQL/Death.cql +1 -1
  8. data/examples/CQL/Diplomacy.cql +9 -9
  9. data/examples/CQL/Genealogy.cql +3 -2
  10. data/examples/CQL/Insurance.cql +10 -7
  11. data/examples/CQL/JoinEquality.cql +2 -2
  12. data/examples/CQL/Marriage.cql +1 -1
  13. data/examples/CQL/Metamodel.cql +73 -53
  14. data/examples/CQL/MetamodelNext.cql +89 -67
  15. data/examples/CQL/OneToOnes.cql +2 -2
  16. data/examples/CQL/ServiceDirector.cql +10 -5
  17. data/examples/CQL/Supervision.cql +3 -3
  18. data/examples/CQL/Tests.Test5.Load.cql +1 -1
  19. data/examples/CQL/Warehousing.cql +4 -2
  20. data/lib/activefacts/cql/CQLParser.treetop +26 -60
  21. data/lib/activefacts/cql/Context.treetop +12 -2
  22. data/lib/activefacts/cql/Expressions.treetop +14 -30
  23. data/lib/activefacts/cql/FactTypes.treetop +165 -110
  24. data/lib/activefacts/cql/Language/English.treetop +167 -54
  25. data/lib/activefacts/cql/LexicalRules.treetop +16 -2
  26. data/lib/activefacts/cql/{Concepts.treetop → ObjectTypes.treetop} +36 -37
  27. data/lib/activefacts/cql/Terms.treetop +57 -27
  28. data/lib/activefacts/cql/ValueTypes.treetop +39 -13
  29. data/lib/activefacts/cql/compiler.rb +5 -3
  30. data/lib/activefacts/cql/compiler/{reading.rb → clause.rb} +407 -285
  31. data/lib/activefacts/cql/compiler/constraint.rb +178 -275
  32. data/lib/activefacts/cql/compiler/entity_type.rb +73 -64
  33. data/lib/activefacts/cql/compiler/expression.rb +418 -0
  34. data/lib/activefacts/cql/compiler/fact.rb +146 -145
  35. data/lib/activefacts/cql/compiler/fact_type.rb +197 -80
  36. data/lib/activefacts/cql/compiler/join.rb +159 -0
  37. data/lib/activefacts/cql/compiler/shared.rb +51 -23
  38. data/lib/activefacts/cql/compiler/value_type.rb +56 -2
  39. data/lib/activefacts/cql/parser.rb +15 -4
  40. data/lib/activefacts/generate/absorption.rb +7 -7
  41. data/lib/activefacts/generate/cql.rb +100 -37
  42. data/lib/activefacts/generate/oo.rb +28 -51
  43. data/lib/activefacts/generate/ordered.rb +60 -36
  44. data/lib/activefacts/generate/ruby.rb +6 -6
  45. data/lib/activefacts/generate/sql/server.rb +4 -4
  46. data/lib/activefacts/input/orm.rb +71 -53
  47. data/lib/activefacts/persistence.rb +1 -1
  48. data/lib/activefacts/persistence/columns.rb +27 -23
  49. data/lib/activefacts/persistence/foreignkey.rb +6 -6
  50. data/lib/activefacts/persistence/index.rb +17 -17
  51. data/lib/activefacts/persistence/{concept.rb → object_type.rb} +9 -9
  52. data/lib/activefacts/persistence/reference.rb +61 -36
  53. data/lib/activefacts/persistence/tables.rb +61 -59
  54. data/lib/activefacts/support.rb +54 -29
  55. data/lib/activefacts/version.rb +1 -1
  56. data/lib/activefacts/vocabulary/extensions.rb +99 -54
  57. data/lib/activefacts/vocabulary/metamodel.rb +43 -37
  58. data/lib/activefacts/vocabulary/verbaliser.rb +134 -109
  59. data/spec/absorption_spec.rb +8 -8
  60. data/spec/cql/comparison_spec.rb +91 -0
  61. data/spec/cql/contractions_spec.rb +251 -0
  62. data/spec/cql/entity_type_spec.rb +319 -0
  63. data/spec/cql/expressions_spec.rb +63 -0
  64. data/spec/cql/fact_type_matching_spec.rb +283 -0
  65. data/spec/cql/french_spec.rb +21 -0
  66. data/spec/cql/parser/bad_literals_spec.rb +86 -0
  67. data/spec/cql/parser/constraints_spec.rb +19 -0
  68. data/spec/cql/parser/entity_types_spec.rb +106 -0
  69. data/spec/cql/parser/expressions_spec.rb +179 -0
  70. data/spec/cql/parser/fact_types_spec.rb +41 -0
  71. data/spec/cql/parser/literals_spec.rb +312 -0
  72. data/spec/cql/parser/pragmas_spec.rb +89 -0
  73. data/spec/cql/parser/value_types_spec.rb +42 -0
  74. data/spec/cql/role_matching_spec.rb +147 -0
  75. data/spec/cql/samples_spec.rb +9 -9
  76. data/spec/cql_cql_spec.rb +1 -1
  77. data/spec/cql_dm_spec.rb +116 -0
  78. data/spec/cql_mysql_spec.rb +1 -1
  79. data/spec/cql_ruby_spec.rb +1 -1
  80. data/spec/cql_sql_spec.rb +3 -3
  81. data/spec/cql_symbol_tables_spec.rb +30 -30
  82. data/spec/cqldump_spec.rb +4 -4
  83. data/spec/helpers/array_matcher.rb +32 -27
  84. data/spec/helpers/diff_matcher.rb +6 -26
  85. data/spec/helpers/file_matcher.rb +41 -32
  86. data/spec/helpers/parse_to_ast_matcher.rb +76 -0
  87. data/spec/helpers/string_matcher.rb +32 -31
  88. data/spec/norma_cql_spec.rb +1 -1
  89. data/spec/norma_ruby_spec.rb +1 -1
  90. data/spec/norma_ruby_sql_spec.rb +1 -1
  91. data/spec/norma_sql_spec.rb +3 -1
  92. data/spec/norma_tables_spec.rb +1 -1
  93. data/spec/ruby_api_spec.rb +23 -0
  94. data/spec/spec_helper.rb +5 -4
  95. metadata +66 -66
  96. data/examples/CQL/OrienteeringER.cql +0 -58
  97. data/lib/activefacts/api.rb +0 -44
  98. data/lib/activefacts/api/concept.rb +0 -410
  99. data/lib/activefacts/api/constellation.rb +0 -128
  100. data/lib/activefacts/api/entity.rb +0 -256
  101. data/lib/activefacts/api/instance.rb +0 -60
  102. data/lib/activefacts/api/instance_index.rb +0 -80
  103. data/lib/activefacts/api/numeric.rb +0 -167
  104. data/lib/activefacts/api/role.rb +0 -80
  105. data/lib/activefacts/api/role_proxy.rb +0 -70
  106. data/lib/activefacts/api/role_values.rb +0 -117
  107. data/lib/activefacts/api/standard_types.rb +0 -87
  108. data/lib/activefacts/api/support.rb +0 -65
  109. data/lib/activefacts/api/value.rb +0 -135
  110. data/lib/activefacts/api/vocabulary.rb +0 -82
  111. data/spec/api/autocounter.rb +0 -82
  112. data/spec/api/constellation.rb +0 -130
  113. data/spec/api/entity_type.rb +0 -103
  114. data/spec/api/instance.rb +0 -461
  115. data/spec/api/roles.rb +0 -124
  116. data/spec/api/value_type.rb +0 -112
  117. data/spec/api_spec.rb +0 -13
  118. data/spec/cql/matching_spec.rb +0 -517
  119. data/spec/cql/unit_spec.rb +0 -394
  120. data/spec/spec.opts +0 -1
@@ -3,8 +3,8 @@ module ActiveFacts
3
3
  class Compiler < ActiveFacts::CQL::Parser
4
4
 
5
5
  class Fact < Definition
6
- def initialize readings, population_name = ''
7
- @readings = readings
6
+ def initialize clauses, population_name = ''
7
+ @clauses = clauses
8
8
  @population_name = population_name
9
9
  end
10
10
 
@@ -12,17 +12,15 @@ module ActiveFacts
12
12
  @population = @constellation.Population(@vocabulary, @population_name)
13
13
 
14
14
  @context = CompilationContext.new(@vocabulary)
15
- @readings.each{ |reading| reading.identify_players_with_role_name(@context) }
16
- @readings.each{ |reading| reading.identify_other_players(@context) }
17
- @readings.each{ |reading| reading.bind_roles @context }
18
- @readings.each{ |reading| reading.match_existing_fact_type @context }
15
+ @context.bind @clauses
16
+ @context.left_contraction_allowed = true
17
+ @clauses.each{ |clause| clause.match_existing_fact_type @context }
19
18
 
20
19
  # Figure out the simple existential facts and find fact types:
21
20
  @bound_facts = []
22
- @ojr_by_role_ref = {}
23
- @unbound_readings = all_readings.
24
- map do |reading|
25
- bind_literal_or_fact_type reading
21
+ @unbound_clauses = all_clauses.
22
+ map do |clause|
23
+ bind_literal_or_fact_type clause
26
24
  end.
27
25
  compact
28
26
 
@@ -32,158 +30,157 @@ module ActiveFacts
32
30
  true while bind_more_facts
33
31
 
34
32
  # Any remaining unbound facts are a problem we can bitch about:
35
- complain_incomplete unless @unbound_readings.empty?
33
+ complain_incomplete unless @unbound_clauses.empty?
36
34
 
37
35
  @bound_facts.uniq # N.B. this includes Instance objects (existential facts)
38
36
  end
39
37
 
40
- def bind_literal_or_fact_type reading
38
+ def bind_literal_or_fact_type clause
41
39
  # Every bound word (term) in the phrases must have a literal
42
40
  # OR be bound to an entity type identified by the phrases
43
41
 
44
- # Any clause that has one binding and no other word is
42
+ # Any clause that has one variable and no other word is
45
43
  # either a value instance or a simply-identified entity.
46
- reading.role_refs.each do |role_ref|
47
- next unless l = role_ref.literal # No literal
48
- next if role_ref.binding.instance # Already bound
49
- player = role_ref.binding.player
50
- # raise "A literal may not be an objectification" if role_ref.role_ref.objectification_join
51
- # raise "Not processing facts involving objectification joins yet" if role_ref.role_ref
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
52
50
  debug :instance, "Making #{player.class.basename} #{player.name} using #{l.inspect}" do
53
- role_ref.binding.instance = instance_identified_by_literal(player, l)
51
+ var_ref.variable.instance = instance_identified_by_literal(player, l)
54
52
  end
55
- role_ref
53
+ var_ref
56
54
  end
57
55
 
58
- if reading.phrases.size == 1 and (role_ref = reading.phrases[0]).is_a?(Compiler::RoleRef)
59
- if role_ref.objectification_join
60
- # Assign the objectified fact type as this reading's fact type?
61
- reading.fact_type = role_ref.player.fact_type
62
- reading
56
+ if clause.phrases.size == 1 and (var_ref = clause.phrases[0]).is_a?(Compiler::VarRef)
57
+ if var_ref.nested_clauses
58
+ # Assign the objectified fact type as this clause's fact type?
59
+ clause.fact_type = var_ref.player.fact_type
60
+ clause
63
61
  else
64
62
  # This is an existential fact (like "Name 'foo'", or "Company 'Microsoft'")
65
63
  nil # Nothing to see here, move along
66
64
  end
67
65
  else
68
- raise "Fact Type not found: '#{reading.display}'" unless reading.fact_type
69
- # This instance will be associated with its binding by our caller
70
- reading
66
+ raise "Fact Type not found: '#{clause.display}'" unless clause.fact_type
67
+ # This instance will be associated with its variable by our caller
68
+ clause
71
69
  end
72
70
  end
73
71
 
74
72
  #
75
- # Try to bind this reading, and return true if it can be completed
73
+ # Try to bind this clause, and return true if it can be completed
76
74
  #
77
- def bind_reading reading
78
- return true if reading.fact
79
-
80
- # Find the roles of this reading that do not yet have an instance
81
- bare_roles = reading.role_refs.
82
- select do |role_ref|
83
- next false if role_ref.binding.instance
84
- next false if role_ref.literal and
85
- role_ref.binding.instance = instance_identified_by_literal(role_ref.binding.player, role_ref.literal)
75
+ def bind_clause clause
76
+ return true if clause.fact
77
+
78
+ # 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)
86
84
  true
87
85
  end
88
86
 
89
- debug :instance, "Considering '#{reading.display}' with "+
90
- (bare_roles.empty? ? "no bare roles" : "bare roles: #{bare_roles.map{|role_ref| role_ref.player.name}*", "}") do
87
+ 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
91
89
 
92
- # If all the roles are in place, we can bind the rest of this reading:
93
- return true if bare_roles.size == 0 && bind_complete_fact(reading)
90
+ # If all the roles are in place, we can bind the rest of this clause:
91
+ return true if bare_roles.size == 0 && bind_complete_fact(clause)
94
92
 
95
93
  progress = false
96
94
  if bare_roles.size == 1 &&
97
- (binding = bare_roles[0].binding) &&
98
- (et = binding.player).is_a?(ActiveFacts::Metamodel::EntityType)
99
- if et.preferred_identifier.role_sequence.all_role_ref.detect{|rr| rr.role.fact_type == reading.fact_type} &&
100
- bind_entity_if_identifier_ready(reading, et, binding)
95
+ (variable = bare_roles[0].variable) &&
96
+ (et = variable.player).is_a?(ActiveFacts::Metamodel::EntityType)
97
+ 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)
101
99
  progress = true
102
100
  end
103
101
  end
104
102
 
105
103
  return true if progress
106
- debug :instance, "Can't make progress on '#{reading.display}'"
104
+ debug :instance, "Can't make progress on '#{clause.display}'"
107
105
  nil
108
106
  end
109
107
  end
110
108
 
111
- # Take one pass through the @unbound_readings, processing (and removing) any that have all pre-requisites
109
+ # Take one pass through the @unbound_clauses, processing (and removing) any that have all pre-requisites
112
110
  def bind_more_facts
113
- return false unless @unbound_readings.size > 0
111
+ return false unless @unbound_clauses.size > 0
114
112
  @pass += 1
115
113
 
116
114
  progress = false
117
- debug :instance, "Pass #{@pass} with #{@unbound_readings.size} readings to consider" do
118
- @unbound_readings =
119
- @unbound_readings.select do |reading|
120
- action = bind_reading(reading)
115
+ debug :instance, "Pass #{@pass} with #{@unbound_clauses.size} clauses to consider" do
116
+ @unbound_clauses =
117
+ @unbound_clauses.select do |clause|
118
+ action = bind_clause(clause)
121
119
  progress = true if action
122
120
  !action
123
121
  end
124
- debug :instance, "end of pass, unbound readings are #{@unbound_readings.map(&:display)*', '}"
122
+ debug :instance, "end of pass, unbound clauses are #{@unbound_clauses.map(&:display)*', '}"
125
123
  end # debug
126
124
  progress
127
125
  end
128
126
 
129
- # Occasionally we need to search through all the readings:
130
- def all_readings
131
- @readings.map do |reading|
132
- [reading] + reading.role_refs.map{|rr| rr.objectification_join}
127
+ # Occasionally we need to search through all the clauses:
128
+ def all_clauses
129
+ @clauses.map do |clause|
130
+ [clause] + clause.var_refs.map{|vr| vr.nested_clauses}
133
131
  end.flatten.compact
134
132
  end
135
133
 
136
- def bind_complete_fact reading
137
- return true unless reading.fact_type # An bare objectification
138
- debug :instance, "All bindings in '#{reading.display}' contain instances; create the fact type"
139
- instances = reading.role_refs.map{|rr| rr.binding.instance}
140
- debug :instance, "Instances are #{instances.map{|i| "#{i.concept.name} #{i.value.inspect}"}*", "}"
134
+ def bind_complete_fact clause
135
+ 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}
138
+ debug :instance, "Instances are #{instances.map{|i| "#{i.object_type.name} #{i.value.inspect}"}*", "}"
141
139
 
142
- if e = reading.fact_type.entity_type and
143
- reading.role_refs[0].binding.instance.concept == e
144
- fact = reading.role_refs[0].binding.instance.fact
140
+ 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
145
143
  else
146
144
  # Check that this fact doesn't already exist
147
- fact = reading.fact_type.all_fact.detect do |f|
148
- # Get the role values of this fact in the order of the reading we just bound
149
- role_values_in_reading_order = f.all_role_value.sort_by do |rv|
150
- debugger unless reading.reading
151
- reading.reading.role_sequence.all_role_ref.detect{|rr| rr.role == rv.role}.ordinal
145
+ fact = clause.fact_type.all_fact.detect do |f|
146
+ # Get the role values of this fact in the order of the clause we just bound
147
+ role_values_in_clause_order = f.all_role_value.sort_by do |rv|
148
+ clause.reading.role_sequence.all_role_ref.detect{|rr| rr.role == rv.role}.ordinal
152
149
  end
153
150
  # If all this fact's role values are played by the bound instances, it's the same fact
154
- !role_values_in_reading_order.zip(instances).detect{|rv, i| rv.instance != i }
151
+ !role_values_in_clause_order.zip(instances).detect{|rv, i| rv.instance != i }
155
152
  end
156
153
  end
157
154
  if fact
158
- reading.fact = fact
155
+ clause.fact = fact
159
156
  debug :instance, "Found existing fact type instance"
160
157
  else
161
158
  fact =
162
- reading.fact =
163
- @constellation.Fact(:new, :fact_type => reading.fact_type, :population => @population)
159
+ clause.fact =
160
+ @constellation.Fact(:new, :fact_type => clause.fact_type, :population => @population)
164
161
  @bound_facts << fact
165
162
 
166
- reading.reading.role_sequence.all_role_ref_in_order.zip(instances).each do |rr, instance|
167
- debug :instance, "New fact has #{instance.concept.name} role #{instance.value.inspect}"
163
+ clause.reading.role_sequence.all_role_ref_in_order.zip(instances).each do |rr, instance|
164
+ debug :instance, "New fact has #{instance.object_type.name} role #{instance.value.inspect}"
168
165
  # REVISIT: Any residual adjectives after the fact type matching are lost here.
169
166
  @constellation.RoleValue(:fact => fact, :instance => instance, :role => rr.role, :population => @population)
170
167
  end
171
168
  end
172
169
 
173
- if !fact.instance && reading.fact_type.entity_type
170
+ if !fact.instance && clause.fact_type.entity_type
174
171
  # Objectified fact type; create the instance
175
- # Create the instance that objectifies this fact. We don't have the binding to assign it to though; that'll happen in our caller
176
- debug :instance, "Objectifying fact as #{reading.fact_type.entity_type.name}"
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
173
+ debug :instance, "Objectifying fact as #{clause.fact_type.entity_type.name}"
177
174
  instance =
178
- @constellation.Instance(:new, :concept => reading.fact_type.entity_type, :fact => fact, :population => @population)
175
+ @constellation.Instance(:new, :object_type => clause.fact_type.entity_type, :fact => fact, :population => @population)
179
176
  @bound_facts << instance
180
177
  end
181
178
 
182
- if reading.fact and
183
- reading.objectified_as and
184
- instance = reading.fact.instance and
185
- instance.concept == reading.objectified_as.binding.player
186
- reading.objectified_as.binding.instance = instance
179
+ if clause.fact and
180
+ clause.objectified_as and
181
+ instance = clause.fact.instance and
182
+ instance.object_type == clause.objectified_as.variable.player
183
+ clause.objectified_as.variable.instance = instance
187
184
  end
188
185
 
189
186
  true
@@ -192,21 +189,21 @@ module ActiveFacts
192
189
  # If we have one bare role (no literal or instance) played by an entity type,
193
190
  # and the bound fact type participates in the identifier, we might now be able
194
191
  # to create the entity instance.
195
- def bind_entity_if_identifier_ready reading, entity_type, binding
192
+ def bind_entity_if_identifier_ready clause, entity_type, variable
196
193
  # Check this instance doesn't already exist already:
197
- identifying_binding = (reading.role_refs.map{|rr| rr.binding}-[binding])[0]
198
- return false unless identifying_binding # This happens when we have a bare objectification
199
- identifying_instance = identifying_binding.instance
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
197
  preferred_identifier = entity_type.preferred_identifier
201
198
 
202
- debug :instance, "This clause associates a new #{binding.player.name} with a #{identifying_binding.player.name}#{identifying_instance ? " which exists" : ""}"
199
+ debug :instance, "This clause associates a new #{variable.player.name} with a #{identifying_variable.player.name}#{identifying_instance ? " which exists" : ""}"
203
200
 
204
201
  identifying_role_ref = preferred_identifier.role_sequence.all_role_ref.detect { |rr|
205
- rr.role.fact_type == reading.fact_type && rr.role.concept == identifying_binding.player
202
+ rr.role.fact_type == clause.fact_type && rr.role.object_type == identifying_variable.player
206
203
  }
207
204
  unless identifying_role_ref
208
- # This shold never happen; we already bound all role_refs
209
- debug :instance, "Failed to find a #{identifying_instance.concept.name}"
205
+ # This shold never happen; we already bound all var_refs
206
+ debug :instance, "Failed to find a #{identifying_instance.object_type.name}"
210
207
  return false # We can't do this yet
211
208
  end
212
209
  role_value = identifying_instance.all_role_value.detect do |rv|
@@ -214,41 +211,41 @@ module ActiveFacts
214
211
  end
215
212
  if role_value
216
213
  instance = (role_value.fact.all_role_value.to_a-[role_value])[0].instance
217
- debug :instance, "Found an existing instance (of #{instance.concept.name}) from a previous definition"
218
- binding.instance = instance
219
- return true # Done with this reading
214
+ debug :instance, "Found an existing instance (of #{instance.object_type.name}) from a previous definition"
215
+ variable.instance = instance
216
+ return true # Done with this clause
220
217
  end
221
218
 
222
219
  pi_role_refs = preferred_identifier.role_sequence.all_role_ref
223
- # For each pi role, we have to find the fact clause, which contains the binding we need.
220
+ # For each pi role, we have to find the fact clause, which contains the variable we need.
224
221
  # Then we have to create an instance of each fact
225
222
  identifiers =
226
223
  pi_role_refs.map do |rr|
227
- # Find a reading that provides the identifying_role_ref for this player:
228
- identifying_reading = all_readings.detect do |reading|
229
- rr.role.fact_type == reading.fact_type &&
230
- reading.role_refs.detect{|r1| r1.binding == binding}
224
+ # Find a clause that provides the identifying_var_ref for this player:
225
+ identifying_clause = all_clauses.detect do |clause|
226
+ rr.role.fact_type == clause.fact_type &&
227
+ clause.var_refs.detect{|vr| vr.variable == variable}
231
228
  end
232
- return false unless identifying_reading
233
- identifying_role_ref = identifying_reading.role_refs.select{|role_ref| role_ref.binding != binding}[0]
234
- identifying_binding = identifying_role_ref ? identifying_role_ref.binding : nil
235
- identifying_instance = identifying_binding.instance
229
+ 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
233
 
237
- [rr, identifying_reading, identifying_binding, identifying_instance]
234
+ [rr, identifying_clause, identifying_variable, identifying_instance]
238
235
  end
239
236
  if identifiers.detect{ |i| !i[3] } # Not all required facts are bound yet
240
- debug :instance, "Can't go through with creating #{binding.player.name}; not all the identifying facts are in"
237
+ debug :instance, "Can't go through with creating #{variable.player.name}; not all the identifying facts are in"
241
238
  return false
242
239
  end
243
240
 
244
- debug :instance, "Going ahead with creating #{binding.player.name} using #{identifiers.size} roles" do
245
- instance = @constellation.Instance(:new, :concept => entity_type, :population => @population)
246
- binding.instance = instance
241
+ debug :instance, "Going ahead with creating #{variable.player.name} using #{identifiers.size} roles" do
242
+ instance = @constellation.Instance(:new, :object_type => entity_type, :population => @population)
243
+ variable.instance = instance
247
244
  @bound_facts << instance
248
- identifiers.each do |rr, identifying_reading, identifying_binding, identifying_instance|
249
- # This reading provides the identifying literal for the entity_type
245
+ identifiers.each do |rr, identifying_clause, identifying_variable, identifying_instance|
246
+ # This clause provides the identifying literal for the entity_type
250
247
  id_fact =
251
- identifying_reading.fact =
248
+ identifying_clause.fact =
252
249
  @constellation.Fact(:new, :fact_type => rr.role.fact_type, :population => @population)
253
250
  @bound_facts << id_fact
254
251
  role = (rr.role.fact_type.all_role.to_a-[rr.role])[0]
@@ -257,14 +254,14 @@ module ActiveFacts
257
254
  end
258
255
  end
259
256
 
260
- true # Done with this reading
257
+ true # Done with this clause
261
258
  end
262
259
 
263
- def instance_identified_by_literal concept, literal
264
- if concept.is_a?(ActiveFacts::Metamodel::EntityType)
265
- entity_identified_by_literal concept, literal
260
+ def instance_identified_by_literal object_type, literal
261
+ if object_type.is_a?(ActiveFacts::Metamodel::EntityType)
262
+ entity_identified_by_literal object_type, literal
266
263
  else
267
- debug :instance, "Making ValueType #{concept.name} #{literal.inspect} #{@population.name.size>0 ? " in "+@population.name.inspect : ''}" do
264
+ debug :instance, "Making ValueType #{object_type.name} #{literal.inspect} #{@population.name.size>0 ? " in "+@population.name.inspect : ''}" do
268
265
 
269
266
  is_a_string = String === literal
270
267
  instance = @constellation.Instance.detect do |key, i|
@@ -274,14 +271,14 @@ module ActiveFacts
274
271
  i.value.literal == literal &&
275
272
  i.value.is_a_string == is_a_string
276
273
  end
277
- #instance = concept.all_instance.detect { |instance|
274
+ #instance = object_type.all_instance.detect { |instance|
278
275
  # instance.population == @population && instance.value == literal
279
276
  #}
280
- debug :instance, "This #{concept.name} value already exists" if instance
277
+ debug :instance, "This #{object_type.name} value already exists" if instance
281
278
  unless instance
282
279
  instance = @constellation.Instance(
283
280
  :new,
284
- :concept => concept,
281
+ :object_type => object_type,
285
282
  :population => @population,
286
283
  :value => [literal.to_s, is_a_string, nil]
287
284
  )
@@ -292,32 +289,32 @@ module ActiveFacts
292
289
  end
293
290
  end
294
291
 
295
- def entity_identified_by_literal concept, literal
292
+ def entity_identified_by_literal object_type, literal
296
293
  # A literal that identifies an entity type means the entity type has only one identifying role
297
294
  # That role is played either by a value type, or by another similarly single-identified entity type
298
- debug "Making EntityType #{concept.name} identified by '#{literal}' #{@population.name.size>0 ? " in "+@population.name.inspect : ''}" do
299
- identifying_role_refs = concept.preferred_identifier.role_sequence.all_role_ref
300
- raise "Single literal cannot satisfy multiple identifying roles for #{concept.name}" if identifying_role_refs.size > 1
295
+ debug "Making EntityType #{object_type.name} identified by '#{literal}' #{@population.name.size>0 ? " in "+@population.name.inspect : ''}" do
296
+ identifying_role_refs = object_type.preferred_identifier.role_sequence.all_role_ref
297
+ raise "Single literal cannot satisfy multiple identifying roles for #{object_type.name}" if identifying_role_refs.size > 1
301
298
  role = identifying_role_refs.single.role
302
- # This instance has no binding; the binding is of the entity type not the identifying value type
303
- identifying_instance = instance_identified_by_literal role.concept, literal
299
+ # This instance has no variable; the variable is of the entity type not the identifying value type
300
+ identifying_instance = instance_identified_by_literal role.object_type, literal
304
301
  existing_instance = nil
305
302
  instance_rv = identifying_instance.all_role_value.detect { |rv|
306
303
  next false unless rv.population == @population # Not this population
307
304
  next false unless rv.fact.fact_type == role.fact_type # Not this fact type
308
305
  other_role_value = (rv.fact.all_role_value-[rv])[0]
309
306
  existing_instance = other_role_value.instance
310
- other_role_value.instance.concept == concept # Is it this concept?
307
+ other_role_value.instance.object_type == object_type # Is it this object_type?
311
308
  }
312
309
  if instance_rv
313
310
  instance = existing_instance
314
- debug :instance, "This #{concept.name} entity already exists"
311
+ debug :instance, "This #{object_type.name} entity already exists"
315
312
  else
316
- # This fact has no reading.
313
+ # This fact has no clause.
317
314
  fact = @constellation.Fact(:new, :fact_type => role.fact_type, :population => @population)
318
315
  @bound_facts << fact
319
- # This instance will be associated with its binding by our caller
320
- instance = @constellation.Instance(:new, :concept => concept, :population => @population)
316
+ # This instance will be associated with its variable by our caller
317
+ instance = @constellation.Instance(:new, :object_type => object_type, :population => @population)
321
318
  @bound_facts << instance
322
319
  # The identifying fact type has two roles; create both role instances:
323
320
  @constellation.RoleValue(:instance => identifying_instance, :fact => fact, :population => @population, :role => role)
@@ -328,30 +325,30 @@ module ActiveFacts
328
325
  end
329
326
 
330
327
  def complain_incomplete
331
- if @unbound_readings.size > 0
332
- # Provide a readable description of the problem here, by showing each binding with no instance
333
- missing_bindings = @unbound_readings.
334
- map do |reading|
335
- reading.role_refs.
336
- select do |rr|
337
- !rr.binding.instance
328
+ if @unbound_clauses.size > 0
329
+ # Provide a readable description of the problem here, by showing each variable with no instance
330
+ missing_variables = @unbound_clauses.
331
+ map do |clause|
332
+ clause.var_refs.
333
+ select do |var_refs|
334
+ !var_refs.variable.instance
338
335
  end.
339
- map do |role_ref|
340
- role_ref.binding
336
+ map do |var_ref|
337
+ var_ref.variable
341
338
  end
342
339
  end.
343
340
  flatten.
344
341
  uniq
345
342
 
346
343
  raise "Not enough facts are given to identify #{
347
- missing_bindings.
344
+ missing_variables.
348
345
  sort_by{|b| b.key}.
349
346
  map do |b|
350
347
  player_identifier =
351
348
  if b.player.is_a?(ActiveFacts::Metamodel::EntityType)
352
349
  "lacking " +
353
350
  b.player.preferred_identifier.role_sequence.all_role_ref.map do |rr|
354
- [ rr.leading_adjective, rr.role.role_name || rr.role.concept.name, rr.trailing_adjective ].compact*" "
351
+ [ rr.leading_adjective, rr.role.role_name || rr.role.object_type.name, rr.trailing_adjective ].compact*" "
355
352
  end*", "
356
353
  else
357
354
  "needs a value"
@@ -365,6 +362,10 @@ module ActiveFacts
365
362
  end
366
363
  end
367
364
 
365
+ def to_s
366
+ super+@clauses.map(&:to_s)*', '
367
+ end
368
+
368
369
  end
369
370
  end
370
371
  end