activefacts 1.1.0 → 1.2.0

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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/bin/cql +137 -91
  3. data/css/style.css +3 -3
  4. data/examples/CQL/Insurance.cql +1 -1
  5. data/examples/CQL/SeparateSubtype.cql +2 -2
  6. data/lib/activefacts/cql/Language/English.treetop +9 -0
  7. data/lib/activefacts/cql/ObjectTypes.treetop +1 -1
  8. data/lib/activefacts/cql/Terms.treetop +3 -1
  9. data/lib/activefacts/cql/ValueTypes.treetop +10 -4
  10. data/lib/activefacts/cql/compiler.rb +1 -0
  11. data/lib/activefacts/cql/compiler/clause.rb +53 -23
  12. data/lib/activefacts/cql/compiler/entity_type.rb +0 -4
  13. data/lib/activefacts/cql/compiler/expression.rb +9 -13
  14. data/lib/activefacts/cql/compiler/fact.rb +49 -48
  15. data/lib/activefacts/cql/compiler/fact_type.rb +23 -20
  16. data/lib/activefacts/cql/compiler/query.rb +49 -121
  17. data/lib/activefacts/cql/compiler/shared.rb +5 -1
  18. data/lib/activefacts/cql/compiler/value_type.rb +4 -2
  19. data/lib/activefacts/generate/rails/schema.rb +138 -108
  20. data/lib/activefacts/generate/transform/surrogate.rb +1 -2
  21. data/lib/activefacts/mapping/rails.rb +52 -45
  22. data/lib/activefacts/persistence/columns.rb +5 -5
  23. data/lib/activefacts/persistence/tables.rb +6 -4
  24. data/lib/activefacts/support.rb +0 -2
  25. data/lib/activefacts/version.rb +1 -1
  26. data/lib/activefacts/vocabulary/extensions.rb +64 -42
  27. data/lib/activefacts/vocabulary/metamodel.rb +14 -12
  28. data/lib/activefacts/vocabulary/verbaliser.rb +98 -92
  29. data/spec/cql/expressions_spec.rb +8 -3
  30. data/spec/cql/parser/entity_types_spec.rb +1 -1
  31. data/spec/cql/parser/expressions_spec.rb +66 -52
  32. data/spec/cql/parser/fact_types_spec.rb +1 -1
  33. data/spec/cql/parser/literals_spec.rb +10 -10
  34. data/spec/cql/parser/pragmas_spec.rb +3 -3
  35. data/spec/cql/parser/value_types_spec.rb +1 -1
  36. metadata +2 -2
@@ -37,8 +37,8 @@ module ActiveFacts
37
37
  to_s
38
38
  end
39
39
 
40
- def inspect phrases = nil
41
- to_s(phrases||@phrases)
40
+ def inspect
41
+ to_s
42
42
  end
43
43
 
44
44
  def to_s phrases = nil
@@ -52,21 +52,34 @@ module ActiveFacts
52
52
  # else 'definitely '
53
53
  end
54
54
  }#{
55
- quotes = false
56
- phrases.inject(""){|s, p|
57
- if String === p
58
- s + (quotes ? '' : (quotes = true; '"')) + p.to_s + ' '
59
- # REVISIT: Add something here when I re-add functions
60
- # elsif FunctionCallChain === p
61
- # s[0..-2] + (quotes ? (quotes = false; '" ') : '') + p.to_s
62
- else # if Reference === p
63
- s[0..-2] + (quotes ? (quotes = false; '" ') : '') + p.to_s +
64
- ((oj = p.nested_clauses) ? ' ('+ oj.map{|c| ((j=c.conjunction) ? j+' ' : '') + c.to_s}*' ' + ')' : '') +
65
- ' '
66
- # else
67
- # raise "Unexpected phrase type in clause: #{p.to_s}"
68
- end
69
- }.sub(/ $/,'') + (quotes ? '"' : '')
55
+ (
56
+ phrases.map do |phrase|
57
+ case phrase
58
+ when String
59
+ '"' + phrase.to_s + '"'
60
+ when Reference
61
+ phrase.to_s +
62
+ if phrase.nested_clauses
63
+ ' (in which ' +
64
+ phrase.nested_clauses.map do |c|
65
+ ((j = c.conjunction) ? j+' ' : '') +
66
+ c.to_s
67
+ end*' ' +
68
+ ')'
69
+ else
70
+ ''
71
+ end
72
+ when Operation
73
+ phrase.inspect
74
+ when Literal
75
+ phrase.inspect
76
+ #when FunctionCallChain # REVISIT: Add something here when I re-add functions
77
+ # phrase.inspect
78
+ else
79
+ raise "Unexpected phrase type in clause: #{phrase.class}"
80
+ end
81
+ end * ' '
82
+ ).gsub(/" "/, ' ')
70
83
  }#{
71
84
  @context_note && ' ' + @context_note.inspect
72
85
  }"
@@ -131,6 +144,22 @@ module ActiveFacts
131
144
  def match_existing_fact_type context, options = {}
132
145
  raise "Cannot match a clause that contains no object types" if refs.size == 0
133
146
  raise "Internal error, clause already matched, should not match again" if @fact_type
147
+
148
+ if is_naked_object_type
149
+ ref = refs[0] # "There can be only one"
150
+ return true unless ref.nested_clauses
151
+ ref.nested_clauses.each do |nested|
152
+ ft = nested.match_existing_fact_type(context)
153
+ raise "Unrecognised fact type #{nested.display} nested under #{inspect}" unless ft
154
+ if (ft.entity_type == ref.player)
155
+ ref.objectification_of = ft
156
+ nested.objectified_as = ref
157
+ end
158
+ end
159
+ raise "#{ref.inspect} contains objectification steps that do not objectify it" unless ref.objectification_of
160
+ return true
161
+ end
162
+
134
163
  # If we fail to match, try a left contraction (or save this for a subsequent left contraction):
135
164
  left_contract_this_onto = context.left_contractable_clause
136
165
  new_conjunction = (conjunction == nil || conjunction == ',')
@@ -195,7 +224,7 @@ module ActiveFacts
195
224
 
196
225
  player_names = players.map{|p| p.name}
197
226
 
198
- trace :matching, "Looking for existing #{players.size}-ary fact types matching '#{inspect(phrases)}'" do
227
+ trace :matching, "Looking for existing #{players.size}-ary fact types matching '#{inspect}'" do
199
228
  trace :matching, "Players are '#{player_names.inspect}'"
200
229
 
201
230
  # Match existing fact types in nested clauses first:
@@ -204,12 +233,12 @@ module ActiveFacts
204
233
  vrs.each do |ref|
205
234
  next if ref.is_a?(Operation)
206
235
  next unless steps = ref.nested_clauses and !steps.empty?
207
- ref.nested_clauses.each do |oj|
208
- ft = oj.match_existing_fact_type(context)
209
- raise "Unrecognised fact type #{oj.display}" unless ft
236
+ ref.nested_clauses.each do |nested|
237
+ ft = nested.match_existing_fact_type(context)
238
+ raise "Unrecognised fact type #{nested.display}" unless ft
210
239
  if (ft && ft.entity_type == ref.player)
211
240
  ref.objectification_of = ft
212
- oj.objectified_as = ref
241
+ nested.objectified_as = ref
213
242
  end
214
243
  end
215
244
  raise "#{ref.inspect} contains objectification steps that do not objectify it" unless ref.objectification_of
@@ -883,7 +912,7 @@ module ActiveFacts
883
912
  end
884
913
 
885
914
  def includes_literals
886
- @nested_clauses && @nested_clauses.detect{|oj| oj.includes_literals}
915
+ @nested_clauses && @nested_clauses.detect{|nested| nested.includes_literals}
887
916
  end
888
917
 
889
918
  # We create value types for the results of arithmetic expressions, and they get assigned here:
@@ -1064,6 +1093,7 @@ module ActiveFacts
1064
1093
  end
1065
1094
  end
1066
1095
 
1096
+ # REVISIT: This needs to handle annotations for some/that/which, etc.
1067
1097
  class Quantifier
1068
1098
  attr_accessor :enforcement
1069
1099
  attr_accessor :context_note
@@ -170,10 +170,6 @@ module ActiveFacts
170
170
  end
171
171
 
172
172
  def create_identifying_fact_type context, clauses
173
- # Remove uninteresting assertions:
174
- clauses.reject!{|clause| clause.is_existential_type }
175
- return nil unless clauses.size > 0 # Nothing interesting was said.
176
-
177
173
  # See if any fact type already exists (this ET cannot be a player, but might objectify it)
178
174
  existing_clauses = clauses.select{ |clause| clause.match_existing_fact_type context }
179
175
  if negation = existing_clauses.detect{|c| c.certainty == false }
@@ -137,10 +137,6 @@ module ActiveFacts
137
137
  @fact_type
138
138
  end
139
139
 
140
- def is_existential_type
141
- false
142
- end
143
-
144
140
  def is_equality_comparison
145
141
  false
146
142
  end
@@ -179,7 +175,7 @@ module ActiveFacts
179
175
  end
180
176
 
181
177
  def result_type_name(context)
182
- "compare#{operator}(#{[@e1,@e2].map{|e| e.player.name}*', '}))"
178
+ "COMPARE#{operator}<#{[@e1,@e2].map{|e| e.player.name}*' WITH '})>"
183
179
  end
184
180
 
185
181
  def is_equality_comparison
@@ -210,7 +206,7 @@ module ActiveFacts
210
206
  def inspect; to_s; end
211
207
 
212
208
  def to_s
213
- "compare#{
209
+ "COMPARE#{
214
210
  operator
215
211
  }(#{
216
212
  case @certainty
@@ -220,7 +216,7 @@ module ActiveFacts
220
216
  end
221
217
  }#{
222
218
  e1.to_s
223
- } #{
219
+ } WITH #{
224
220
  e2.to_s
225
221
  }#{
226
222
  @qualifiers.empty? ? '' : ', ['+@qualifiers*', '+']'
@@ -255,7 +251,7 @@ module ActiveFacts
255
251
  end
256
252
 
257
253
  def result_type_name(context)
258
- "sum(#{ @terms.map{|f| f.player.name}*', ' })"
254
+ "SUM_OF<#{ @terms.map{|f| f.player.name}*', ' }>"
259
255
  end
260
256
 
261
257
  =begin
@@ -269,7 +265,7 @@ module ActiveFacts
269
265
  def inspect; to_s; end
270
266
 
271
267
  def to_s
272
- 'sum(' + @terms.map{|term| "#{term.to_s}" } * ' ' + ')'
268
+ 'SUM(' + @terms.map{|term| "#{term.to_s}" } * ' PLUS ' + ')'
273
269
  end
274
270
  end
275
271
 
@@ -299,7 +295,7 @@ module ActiveFacts
299
295
  end
300
296
 
301
297
  def result_type_name(context)
302
- "product(#{ @factors.map{|f| f.player.name}*', ' })"
298
+ "PRODUCT_OF<#{ @factors.map{|f| f.player.name}*' ' }>"
303
299
  end
304
300
 
305
301
  =begin
@@ -313,7 +309,7 @@ module ActiveFacts
313
309
  def inspect; to_s; end
314
310
 
315
311
  def to_s
316
- 'product(' + @factors.map{|factor| "#{factor.to_s}" } * ' ' + ')'
312
+ 'PRODUCT(' + @factors.map{|factor| "#{factor.to_s}" } * ' TIMES ' + ')'
317
313
  end
318
314
  end
319
315
 
@@ -350,7 +346,7 @@ module ActiveFacts
350
346
  def inspect; to_s; end
351
347
 
352
348
  def to_s
353
- "reciprocal(#{factor.to_s})"
349
+ "RECIPROCAL(#{factor.to_s})"
354
350
  end
355
351
  end
356
352
 
@@ -381,7 +377,7 @@ module ActiveFacts
381
377
  def inspect; to_s; end
382
378
 
383
379
  def to_s
384
- "negate(#{term.to_s})"
380
+ "NEGATIVE(#{term.to_s})"
385
381
  end
386
382
  end
387
383
 
@@ -24,7 +24,7 @@ module ActiveFacts
24
24
 
25
25
  # Figure out the simple existential facts and find fact types:
26
26
  @bound_facts = []
27
- @unbound_clauses = all_clauses.
27
+ @unbound_clauses = all_clauses(@clauses).
28
28
  map do |clause|
29
29
  bind_literal_or_fact_type clause
30
30
  end.
@@ -53,7 +53,7 @@ module ActiveFacts
53
53
  player = ref.binding.player
54
54
  # raise "A literal may not be an objectification" if ref.role_ref.nested_clauses
55
55
  # raise "Not processing facts involving nested clauses yet" if ref.role_ref
56
- trace :instance, "Making #{player.class.basename} #{player.name} using #{l.inspect}" do
56
+ trace :instance_detail, "Making #{player.class.basename} #{player.name} using #{l.inspect}" do
57
57
  ref.binding.instance = instance_identified_by_literal(player, l)
58
58
  end
59
59
  ref
@@ -92,8 +92,8 @@ module ActiveFacts
92
92
  true
93
93
  end
94
94
 
95
- trace :instance, "Considering '#{clause.display}' with "+
96
- (bare_roles.empty? ? "no bare roles" : "bare roles: #{bare_roles.map{|ref| ref.player.name}*", "}") do
95
+ trace :instance_detail, "Considering '#{clause.display}' with "+
96
+ (bare_roles.empty? ? "no bare roles" : "bare roles: #{bare_roles.map{|ref| ref.player.name}*", "}") do
97
97
 
98
98
  # If all the roles are in place, we can bind the rest of this clause:
99
99
  return true if bare_roles.size == 0 && bind_complete_fact(clause)
@@ -109,7 +109,7 @@ module ActiveFacts
109
109
  end
110
110
 
111
111
  return true if progress
112
- trace :instance, "Can't make progress on '#{clause.display}'"
112
+ trace :instance_detail, "Delaying until all role players are asserted: #{clause.fact_type.default_reading.inspect}"
113
113
  nil
114
114
  end
115
115
  end
@@ -120,37 +120,36 @@ module ActiveFacts
120
120
  @pass += 1
121
121
 
122
122
  progress = false
123
- trace :instance, "Pass #{@pass} with #{@unbound_clauses.size} clauses to consider" do
123
+ trace :instance_detail, "Pass #{@pass} with #{@unbound_clauses.size} clauses to consider" do
124
124
  @unbound_clauses =
125
125
  @unbound_clauses.select do |clause|
126
126
  action = bind_clause(clause)
127
127
  progress = true if action
128
128
  !action
129
129
  end
130
- trace :instance, "end of pass, unbound clauses are #{@unbound_clauses.map(&:display)*', '}"
130
+ trace :instance_detail, "end of pass, unbound clauses are #{@unbound_clauses.map(&:display)*', '}"
131
131
  end # debug
132
132
  progress
133
133
  end
134
134
 
135
- # Occasionally we need to search through all the clauses:
136
- def all_clauses
137
- @clauses.map do |clause|
138
- [clause] + clause.refs.map{|vr| vr.nested_clauses}
135
+ # Occasionally we need to search through all the clauses. This builds a flat list
136
+ def all_clauses clauses
137
+ clauses.map do |clause|
138
+ [clause] + clause.refs.map{|vr| vr.nested_clauses ? all_clauses(vr.nested_clauses) : []}
139
139
  end.flatten.compact
140
140
  end
141
141
 
142
142
  def bind_complete_fact clause
143
143
  return true unless clause.fact_type # An bare objectification
144
- trace :instance, "All bindings in '#{clause.display}' contain instances; assert the fact type"
145
144
  instances = clause.refs.map{|vr| vr.binding.instance }
146
- trace :instance, "Instances are #{instances.map{|i| "#{i.verbalise}"}*", "}"
145
+ trace :instance_detail, "All role players exist for #{clause.display.inspect} exist: #{instances.map{|i| "#{i.verbalise}"}*", "}"
147
146
 
148
147
  if e = clause.fact_type.entity_type and
149
148
  clause.refs[0].binding.instance.object_type == e
150
149
  fact = clause.refs[0].binding.instance.fact
151
150
  else
152
151
  # Check that this fact doesn't already exist
153
- trace :instance, "Searching for existing fact instance"
152
+ trace :instance_detail, "Searching for existing fact instance"
154
153
 
155
154
  fact = clause.fact_type.all_fact.detect do |f|
156
155
 
@@ -165,26 +164,27 @@ module ActiveFacts
165
164
  end
166
165
  if fact
167
166
  clause.fact = fact
168
- trace :instance, "Found existing fact"
167
+ trace :instance, "Already known: #{fact.verbalise.inspect}"
169
168
  else
170
- trace :instance, "Creating new fact of type #{clause.fact_type.default_reading}"
169
+ trace :instance_detail, "Asserting fact of type #{clause.fact_type.default_reading.inspect}"
171
170
  fact =
172
171
  clause.fact =
173
172
  @constellation.Fact(:new, :fact_type => clause.fact_type, :population => @population)
174
173
  @bound_facts << fact
175
174
  clause.reading.role_sequence.all_role_ref_in_order.zip(instances).each do |rr, instance|
176
- trace :instance, "Assigning fact role #{instance.object_type.name} to #{instance.value ? instance.value.inspect : instance.verbalise}"
175
+ trace :instance_detail, "Assigning fact role #{instance.object_type.name} to #{instance.value ? instance.value.inspect : instance.verbalise}"
177
176
  # REVISIT: Any residual adjectives after the fact type matching are lost here.
178
177
  @constellation.RoleValue(:fact => fact, :instance => instance, :role => rr.role, :population => @population)
179
178
  end
179
+ trace :instance, "Assert #{fact.verbalise.inspect} #{@population.name.size>0 ? " in "+@population.name.inspect : ''}" unless clause.fact_type.entity_type
180
180
  end
181
181
 
182
182
  if !fact.instance && clause.fact_type.entity_type
183
183
  # Objectified fact type; create the instance
184
184
  # Create the instance that objectifies this fact. We don't have the binding to assign it to though; that'll happen in our caller
185
- trace :instance, "Objectifying fact as #{clause.fact_type.entity_type.name}"
186
185
  instance =
187
186
  @constellation.Instance(:new, :object_type => clause.fact_type.entity_type, :fact => fact, :population => @population)
187
+ trace :instance, "Assert #{instance.verbalise.inspect}"
188
188
  @bound_facts << instance
189
189
  end
190
190
 
@@ -207,23 +207,24 @@ module ActiveFacts
207
207
  return false unless identifying_binding # This happens when we have a bare objectification
208
208
  identifying_instance = identifying_binding.instance
209
209
  preferred_identifier = entity_type.preferred_identifier
210
+ role_count = preferred_identifier.role_sequence.all_role_ref.size
210
211
 
211
- trace :instance, "This clause associates a new #{binding.player.name} with a #{identifying_binding.player.name}#{identifying_instance ? " which exists" : ""}"
212
+ trace :instance, "A #{binding.player.name} is #{role_count > 1 ? 'partly ':''}identified in #{clause.inspect}"
212
213
 
213
214
  identifying_role_ref = preferred_identifier.role_sequence.all_role_ref.detect { |rr|
214
215
  rr.role.fact_type == clause.fact_type && rr.role.object_type == identifying_binding.player
215
216
  }
216
217
  unless identifying_role_ref
217
- # This shold never happen; we already bound all refs
218
+ # This should never happen; we already bound all refs
218
219
  trace :instance, "Failed to find a #{identifying_instance.object_type.name}"
219
220
  return false # We can't do this yet
220
221
  end
221
222
  role_value = identifying_instance.all_role_value.detect do |rv|
222
223
  rv.fact.fact_type == identifying_role_ref.role.fact_type
223
224
  end
224
- if role_value
225
+ if role_value && role_count == 1
225
226
  instance = (role_value.fact.all_role_value.to_a-[role_value])[0].instance
226
- trace :instance, "Found an existing instance (of #{instance.object_type.name}) from a previous definition"
227
+ trace :instance, "Existential fact already known: #{instance.verbalise.inspect}"
227
228
  binding.instance = instance
228
229
  return true # Done with this clause
229
230
  end
@@ -234,7 +235,7 @@ module ActiveFacts
234
235
  identifiers =
235
236
  pi_role_refs.map do |rr|
236
237
  # Find a clause that provides the identifying_ref for this player:
237
- identifying_clause = all_clauses.detect do |clause|
238
+ identifying_clause = all_clauses(@clauses).detect do |clause|
238
239
  rr.role.fact_type == clause.fact_type &&
239
240
  clause.refs.detect{|vr| vr.binding == binding}
240
241
  end
@@ -250,22 +251,21 @@ module ActiveFacts
250
251
  return false
251
252
  end
252
253
 
253
- trace :instance, "Creating Entity #{binding.player.name} using #{identifiers.size} roles" do
254
- instance = @constellation.Instance(:new, :object_type => entity_type, :population => @population)
255
- binding.instance = instance
256
- @bound_facts << instance
257
- identifiers.each do |rr, identifying_clause, identifying_binding, identifying_instance|
258
- # This clause provides the identifying literal for the entity_type
259
- trace :instance, "Creating existential fact #{rr.role.fact_type.default_reading} for value #{identifying_instance.value.inspect}"
260
- id_fact =
261
- identifying_clause.fact =
262
- @constellation.Fact(:new, :fact_type => rr.role.fact_type, :population => @population)
263
- @bound_facts << id_fact
264
- role = (rr.role.fact_type.all_role.to_a-[rr.role])[0]
265
- @constellation.RoleValue(:instance => instance, :fact => id_fact, :population => @population, :role => role)
266
- @constellation.RoleValue(:instance => identifying_instance, :fact => id_fact, :role => rr.role, :population => @population)
267
- end
268
- end
254
+ instance = @constellation.Instance(:new, :object_type => entity_type, :population => @population)
255
+ binding.instance = instance
256
+ @bound_facts << instance
257
+ identifiers.each do |rr, identifying_clause, identifying_binding, identifying_instance|
258
+ # This clause provides the identifying literal for the entity_type
259
+ id_fact =
260
+ identifying_clause.fact =
261
+ @constellation.Fact(:new, :fact_type => rr.role.fact_type, :population => @population)
262
+ @bound_facts << id_fact
263
+ role = (rr.role.fact_type.all_role.to_a-[rr.role])[0]
264
+ @constellation.RoleValue(:instance => instance, :fact => id_fact, :population => @population, :role => role)
265
+ @constellation.RoleValue(:instance => identifying_instance, :fact => id_fact, :role => rr.role, :population => @population)
266
+ trace :instance, "Assert #{id_fact.verbalise.inspect} (existential) #{@population.name.size>0 ? " in "+@population.name.inspect : ''}"
267
+ end
268
+ trace :instance, "Assert #{instance.verbalise.inspect} #{@population.name.size>0 ? " in "+@population.name.inspect : ''}"
269
269
 
270
270
  true # Done with this clause
271
271
  end
@@ -274,29 +274,29 @@ module ActiveFacts
274
274
  if object_type.is_a?(ActiveFacts::Metamodel::EntityType)
275
275
  entity_identified_by_literal object_type, literal
276
276
  else
277
- trace :instance, "Assert Value #{object_type.name} #{literal.inspect}" do
277
+ trace :instance_detail, "Assert Value #{object_type.name} #{literal.inspect}" do
278
278
  is_literal_string = literal.literal.is_a?(String)
279
279
  # REVISIT: Check for subtypes and supertypes also, and promote type if necessary
280
280
  instance = object_type.all_instance.detect do |i|
281
281
  #instance = @constellation.Instance.detect do |key, i|
282
282
  # REVISIT: And same unit
283
- trace :instance, "Comparing #{i.value.literal.inspect} to #{literal.literal.inspect}"
283
+ trace :instance_detail2, "Comparing #{i.value.literal.inspect} to #{literal.literal.to_s.inspect}"
284
284
  i.population == @population &&
285
285
  i.value &&
286
- i.value.literal.inspect == literal.literal.inspect &&
286
+ i.value.literal.inspect == literal.literal.to_s.inspect &&
287
287
  i.value.is_literal_string == is_literal_string
288
288
  end
289
289
  #instance = object_type.all_instance.detect { |instance|
290
290
  # instance.population == @population && instance.value == literal
291
291
  #}
292
292
  if instance
293
- trace :instance, "This #{object_type.name} value already exists"
293
+ trace :instance, "Instance already known: #{instance.verbalise.inspect}"
294
294
  else
295
- trace :instance, "Creating Value #{object_type.name} #{literal.inspect} #{@population.name.size>0 ? " in "+@population.name.inspect : ''}"
296
295
  instance = @constellation.Instance(:new)
297
296
  instance.object_type = object_type
298
297
  instance.population = @population
299
298
  instance.value = [literal.to_s, is_literal_string, nil]
299
+ trace :instance, "Assert #{instance.verbalise.inspect} #{@population.name.size>0 ? " in "+@population.name.inspect : ''}"
300
300
  @bound_facts << instance
301
301
  end
302
302
  instance
@@ -307,7 +307,7 @@ module ActiveFacts
307
307
  def entity_identified_by_literal object_type, literal
308
308
  # A literal that identifies an entity type means the entity type has only one identifying role
309
309
  # That role is played either by a value type, or by another similarly single-identified entity type
310
- trace :instance, "Assert Entity #{object_type.name} identified by '#{literal}'" do
310
+ trace :instance_detail, "Assert Entity #{object_type.name} identified by '#{literal}'" do
311
311
  identifying_role_refs = object_type.preferred_identifier.role_sequence.all_role_ref
312
312
  raise "Single literal cannot satisfy multiple identifying roles for #{object_type.name}" if identifying_role_refs.size > 1
313
313
  role = identifying_role_refs.single.role
@@ -323,19 +323,20 @@ module ActiveFacts
323
323
  }
324
324
  if instance_rv
325
325
  instance = existing_instance
326
- trace :instance, "This #{object_type.name} entity already exists"
326
+ trace :instance, "Already known: #{instance.verbalise.inspect}"
327
327
  else
328
328
  # This fact has no clause.
329
- trace :instance, "Creating implicit existential fact #{role.fact_type.default_reading}"
329
+ trace :instance_detail, "Creating implicit existential fact #{role.fact_type.default_reading}"
330
330
  fact = @constellation.Fact(:new, :fact_type => role.fact_type, :population => @population)
331
331
  @bound_facts << fact
332
332
  # This instance will be associated with its binding by our caller
333
333
  instance = @constellation.Instance(:new, :object_type => object_type, :population => @population)
334
- trace :instance, "Creating Entity #{object_type.name} identified by '#{literal}' #{@population.name.size>0 ? " in "+@population.name.inspect : ''}"
334
+ trace :instance_detail, "Creating Entity #{object_type.name} identified by '#{literal}' #{@population.name.size>0 ? " in "+@population.name.inspect : ''}"
335
335
  @bound_facts << instance
336
336
  # The identifying fact type has two roles; create both role instances:
337
337
  @constellation.RoleValue(:instance => identifying_instance, :fact => fact, :population => @population, :role => role)
338
338
  @constellation.RoleValue(:instance => instance, :fact => fact, :population => @population, :role => (role.fact_type.all_role-[role])[0])
339
+ trace :instance, "Assert #{instance.verbalise.inspect}"
339
340
  end
340
341
  instance
341
342
  end