activefacts 1.0.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +5 -13
  2. data/Rakefile +2 -2
  3. data/bin/afgen +1 -1
  4. data/bin/cql +118 -27
  5. data/examples/CQL/Insurance.cql +2 -2
  6. data/examples/CQL/Metamodel.cql +3 -3
  7. data/examples/CQL/SchoolActivities.cql +1 -1
  8. data/examples/CQL/Warehousing.cql +5 -4
  9. data/lib/activefacts/cql.rb +1 -1
  10. data/lib/activefacts/cql/Language/English.treetop +2 -1
  11. data/lib/activefacts/cql/compiler.rb +6 -6
  12. data/lib/activefacts/cql/compiler/clause.rb +69 -46
  13. data/lib/activefacts/cql/compiler/constraint.rb +14 -14
  14. data/lib/activefacts/cql/compiler/entity_type.rb +24 -24
  15. data/lib/activefacts/cql/compiler/fact.rb +40 -27
  16. data/lib/activefacts/cql/compiler/fact_type.rb +16 -16
  17. data/lib/activefacts/cql/compiler/query.rb +12 -12
  18. data/lib/activefacts/cql/compiler/shared.rb +9 -0
  19. data/lib/activefacts/cql/compiler/value_type.rb +4 -4
  20. data/lib/activefacts/cql/parser.rb +9 -9
  21. data/lib/activefacts/generate/cql.rb +41 -20
  22. data/lib/activefacts/generate/helpers/oo.rb +33 -70
  23. data/lib/activefacts/generate/helpers/ordered.rb +61 -87
  24. data/lib/activefacts/generate/ruby.rb +12 -72
  25. data/lib/activefacts/generate/transform/surrogate.rb +13 -13
  26. data/lib/activefacts/input/orm.rb +72 -71
  27. data/lib/activefacts/persistence/columns.rb +66 -31
  28. data/lib/activefacts/persistence/foreignkey.rb +6 -6
  29. data/lib/activefacts/persistence/index.rb +12 -12
  30. data/lib/activefacts/persistence/object_type.rb +15 -12
  31. data/lib/activefacts/persistence/reference.rb +20 -18
  32. data/lib/activefacts/persistence/tables.rb +40 -36
  33. data/lib/activefacts/support.rb +69 -123
  34. data/lib/activefacts/version.rb +2 -2
  35. data/lib/activefacts/vocabulary/extensions.rb +42 -39
  36. data/lib/activefacts/vocabulary/metamodel.rb +11 -1
  37. data/lib/activefacts/vocabulary/verbaliser.rb +28 -28
  38. data/spec/cql/contractions_spec.rb +1 -1
  39. data/spec/cql/entity_type_spec.rb +1 -1
  40. data/spec/cql/fact_type_matching_spec.rb +3 -3
  41. data/spec/cql/role_matching_spec.rb +4 -4
  42. data/spec/cql/samples_spec.rb +2 -2
  43. data/spec/cql_cql_spec.rb +1 -1
  44. data/spec/helpers/array_matcher.rb +1 -1
  45. data/spec/norma_ruby_sql_spec.rb +2 -2
  46. data/spec/norma_tables_spec.rb +3 -2
  47. metadata +47 -68
@@ -10,7 +10,7 @@ module ActiveFacts
10
10
  def finalise
11
11
  constellation.FactType.values.each do |fact_type|
12
12
  if c = fact_type.check_and_add_spanning_uniqueness_constraint
13
- debug :constraint, "Checking for existence of at least one uniqueness constraint over the roles of #{fact_type.default_reading.inspect}"
13
+ trace :constraint, "Checking for existence of at least one uniqueness constraint over the roles of #{fact_type.default_reading.inspect}"
14
14
  fact_type.check_and_add_spanning_uniqueness_constraint = nil
15
15
  c.call
16
16
  end
@@ -166,7 +166,6 @@ module ActiveFacts
166
166
  end
167
167
 
168
168
  def is_mandatory
169
- link_fact_type ||
170
169
  all_role_ref.detect{|rr|
171
170
  rs = rr.role_sequence
172
171
  rs.all_role_ref.size == 1 and
@@ -185,12 +184,16 @@ module ActiveFacts
185
184
  def is_functional
186
185
  fact_type.entity_type or
187
186
  fact_type.all_role.size != 2 or
188
- all_role_ref.detect do |rr|
189
- rr.role_sequence.all_role_ref.size == 1 and
190
- rr.role_sequence.all_presence_constraint.detect do |pc|
191
- pc.max_frequency == 1 and !pc.enforcement # Alethic uniqueness constraint
192
- end
193
- end
187
+ is_unique
188
+ end
189
+
190
+ def is_unique
191
+ all_role_ref.detect do |rr|
192
+ rr.role_sequence.all_role_ref.size == 1 and
193
+ rr.role_sequence.all_presence_constraint.detect do |pc|
194
+ pc.max_frequency == 1 and !pc.enforcement # Alethic uniqueness constraint
195
+ end
196
+ end
194
197
  end
195
198
 
196
199
  end
@@ -289,7 +292,7 @@ module ActiveFacts
289
292
 
290
293
  # For a nested fact type, the PI is a unique constraint over N or N-1 roles
291
294
  fact_roles = Array(fact_type.all_role)
292
- debug :pi, "Looking for PI on nested fact type #{name}" do
295
+ trace :pi, "Looking for PI on nested fact type #{name}" do
293
296
  pi = catch :pi do
294
297
  fact_roles[0,2].each{|r| # Try the first two roles of the fact type, that's enough
295
298
  r.all_role_ref.map{|rr| # All role sequences that reference this role
@@ -323,18 +326,18 @@ module ActiveFacts
323
326
  }
324
327
  throw :pi, nil
325
328
  end
326
- debug :pi, "Got PI #{pi.name||pi.object_id} for nested #{name}" if pi
327
- debug :pi, "Looking for PI on entity that nests this fact" unless pi
329
+ trace :pi, "Got PI #{pi.name||pi.object_id} for nested #{name}" if pi
330
+ trace :pi, "Looking for PI on entity that nests this fact" unless pi
328
331
  raise "Oops, pi for nested fact is #{pi.class}" unless !pi || pi.is_a?(ActiveFacts::Metamodel::PresenceConstraint)
329
332
  return @preferred_identifier = pi if pi
330
333
  end
331
334
  end
332
335
 
333
- debug :pi, "Looking for PI for ordinary entity #{name} with #{all_role.size} roles:" do
334
- debug :pi, "Roles are in fact types #{all_role.map{|r| r.fact_type.describe(r)}*", "}"
336
+ trace :pi, "Looking for PI for ordinary entity #{name} with #{all_role.size} roles:" do
337
+ trace :pi, "Roles are in fact types #{all_role.map{|r| r.fact_type.describe(r)}*", "}"
335
338
  pi = catch :pi do
336
339
  all_supertypes = supertypes_transitive
337
- debug :pi, "PI roles must be played by one of #{all_supertypes.map(&:name)*", "}" if all_supertypes.size > 1
340
+ trace :pi, "PI roles must be played by one of #{all_supertypes.map(&:name)*", "}" if all_supertypes.size > 1
338
341
  all_role.each{|role|
339
342
  next unless role.unique || fact_type
340
343
  ftroles = Array(role.fact_type.all_role)
@@ -342,41 +345,41 @@ module ActiveFacts
342
345
  # Skip roles in ternary and higher fact types, they're objectified, and in unaries, they can't identify us.
343
346
  next if ftroles.size != 2
344
347
 
345
- debug :pi, "Considering role in #{role.fact_type.describe(role)}"
348
+ trace :pi, "Considering role in #{role.fact_type.describe(role)}"
346
349
 
347
350
  # Find the related role which must be included in any PI:
348
351
  # Note this works with unary fact types:
349
352
  pi_role = ftroles[ftroles[0] != role ? 0 : -1]
350
353
 
351
354
  next if ftroles.size == 2 && pi_role.object_type == self
352
- debug :pi, " Considering #{pi_role.object_type.name} as a PI role"
355
+ trace :pi, " Considering #{pi_role.object_type.name} as a PI role"
353
356
 
354
357
  # If this is an identifying role, the PI is a PC whose role_sequence spans the role.
355
358
  # Walk through all role_sequences that span this role, and test each:
356
359
  pi_role.all_role_ref.each{|rr|
357
360
  role_sequence = rr.role_sequence # A role sequence that includes a possible role
358
361
 
359
- debug :pi, " Considering role sequence #{role_sequence.describe}"
362
+ trace :pi, " Considering role sequence #{role_sequence.describe}"
360
363
 
361
364
  # All roles in this role_sequence must be in fact types which
362
365
  # (apart from that role) only have roles played by the original
363
366
  # entity type or a supertype.
364
- #debug :pi, " All supertypes #{all_supertypes.map{|st| "#{st.object_id}=>#{st.name}"}*", "}"
367
+ #trace :pi, " All supertypes #{all_supertypes.map{|st| "#{st.object_id}=>#{st.name}"}*", "}"
365
368
  if role_sequence.all_role_ref.detect{|rsr|
366
369
  fact_type = rsr.role.fact_type
367
- debug :pi, " Role Sequence touches #{fact_type.describe(pi_role)}"
370
+ trace :pi, " Role Sequence touches #{fact_type.describe(pi_role)}"
368
371
 
369
372
  fact_type_roles = fact_type.all_role
370
- debug :pi, " residual is #{fact_type_roles.map{|r| r.object_type.name}.inspect} minus #{rsr.role.object_type.name}"
373
+ trace :pi, " residual is #{fact_type_roles.map{|r| r.object_type.name}.inspect} minus #{rsr.role.object_type.name}"
371
374
  residual_roles = fact_type_roles-[rsr.role]
372
375
  residual_roles.detect{|rfr|
373
- debug :pi, " Checking residual role #{rfr.object_type.object_id}=>#{rfr.object_type.name}"
376
+ trace :pi, " Checking residual role #{rfr.object_type.object_id}=>#{rfr.object_type.name}"
374
377
  # This next line looks right, but breaks things. Find out what and why:
375
378
  # !rfr.unique or
376
379
  !all_supertypes.include?(rfr.object_type)
377
380
  }
378
381
  }
379
- debug :pi, " Discounting this role_sequence because it includes alien roles"
382
+ trace :pi, " Discounting this role_sequence because it includes alien roles"
380
383
  next
381
384
  end
382
385
 
@@ -384,7 +387,7 @@ module ActiveFacts
384
387
  rr.role_sequence.all_presence_constraint.detect{|pc|
385
388
  # Found it!
386
389
  if pc.is_preferred_identifier
387
- debug :pi, "found PI #{pc.name||pc.object_id}, is_preferred_identifier=#{pc.is_preferred_identifier.inspect} over #{pc.role_sequence.describe}"
390
+ trace :pi, "found PI #{pc.name||pc.object_id}, is_preferred_identifier=#{pc.is_preferred_identifier.inspect} over #{pc.role_sequence.describe}"
388
391
  throw :pi, pc
389
392
  end
390
393
  }
@@ -393,13 +396,13 @@ module ActiveFacts
393
396
  throw :pi, nil
394
397
  end
395
398
  raise "Oops, pi for entity is #{pi.class}" if pi && !pi.is_a?(ActiveFacts::Metamodel::PresenceConstraint)
396
- debug :pi, "Got PI #{pi.name||pi.object_id} for #{name}" if pi
399
+ trace :pi, "Got PI #{pi.name||pi.object_id} for #{name}" if pi
397
400
 
398
401
  if !pi
399
402
  if (supertype = identifying_supertype)
400
403
  # This shouldn't happen now, as an identifying supertype is connected by a fact type
401
404
  # that has a uniqueness constraint marked as the preferred identifier.
402
- #debug :pi, "PI not found for #{name}, looking in supertype #{supertype.name}"
405
+ #trace :pi, "PI not found for #{name}, looking in supertype #{supertype.name}"
403
406
  #pi = supertype.preferred_identifier
404
407
  #return nil
405
408
  elsif fact_type
@@ -420,11 +423,11 @@ module ActiveFacts
420
423
  break if pi
421
424
  }
422
425
  if !pi && possible_pi
423
- debug :pi, "Using existing PC as PI for #{name}"
426
+ trace :pi, "Using existing PC as PI for #{name}"
424
427
  pi = possible_pi
425
428
  end
426
429
  else
427
- debug :pi, "No PI found for #{name}"
430
+ trace :pi, "No PI found for #{name}"
428
431
  end
429
432
  end
430
433
  raise "No PI found for #{name}" unless pi
@@ -464,14 +467,14 @@ module ActiveFacts
464
467
 
465
468
  # A subtype does not have a identifying_supertype if it defines its own identifier
466
469
  def identifying_supertype
467
- debug "Looking for identifying_supertype of #{name}"
470
+ trace "Looking for identifying_supertype of #{name}"
468
471
  all_type_inheritance_as_subtype.detect{|ti|
469
- debug "considering supertype #{ti.supertype.name}"
472
+ trace "considering supertype #{ti.supertype.name}"
470
473
  next unless ti.provides_identification
471
- debug "found identifying supertype of #{name}, it's #{ti.supertype.name}"
474
+ trace "found identifying supertype of #{name}, it's #{ti.supertype.name}"
472
475
  return ti.supertype
473
476
  }
474
- debug "Failed to find identifying supertype of #{name}"
477
+ trace "Failed to find identifying supertype of #{name}"
475
478
  return nil
476
479
  end
477
480
 
@@ -551,7 +554,7 @@ module ActiveFacts
551
554
  end
552
555
  }
553
556
  expanded.gsub!(/ ?- ?/, '-') # Remove single spaces around adjectives
554
- #debug "Expanded '#{expanded}' using #{frequency_constraints.inspect}"
557
+ #trace "Expanded '#{expanded}' using #{frequency_constraints.inspect}"
555
558
  expanded
556
559
  end
557
560
 
@@ -621,7 +624,7 @@ module ActiveFacts
621
624
  def to_s
622
625
  if all_allowed_range.size > 1
623
626
  "[" +
624
- all_allowed_range.sorted.map { |ar| ar.to_s(true) }*", " +
627
+ all_allowed_range_sorted.map { |ar| ar.to_s(true) }*", " +
625
628
  "]"
626
629
  else
627
630
  all_allowed_range.single.to_s
@@ -777,17 +780,17 @@ module ActiveFacts
777
780
  class Query
778
781
  def show
779
782
  steps_shown = {}
780
- debug :query, "Displaying full contents of Query #{concept.guid}" do
783
+ trace :query, "Displaying full contents of Query #{concept.guid}" do
781
784
  all_variable.sort_by{|jn| jn.ordinal}.each do |variable|
782
- debug :query, "#{variable.describe}" do
785
+ trace :query, "#{variable.describe}" do
783
786
  variable.all_step.
784
787
  each do |step|
785
788
  next if steps_shown[step]
786
789
  steps_shown[step] = true
787
- debug :query, "#{step.describe}"
790
+ trace :query, "#{step.describe}"
788
791
  end
789
792
  variable.all_play.each do |play|
790
- debug :query, "role of #{play.describe} in '#{play.role.fact_type.default_reading}'"
793
+ trace :query, "role of #{play.describe} in '#{play.role.fact_type.default_reading}'"
791
794
  end
792
795
  end
793
796
  end
@@ -979,9 +982,9 @@ module ActiveFacts
979
982
  # Discount a subtype step over an object type that's not a player here,
980
983
  # if we can use an objectification step to an object type that is:
981
984
  if counterpart_sups.size > 0 && obj_sups.size > 0 && counterpart_sups[0] != obj_sups[0]
982
- debug :query, "ambiguous query, could be over #{counterpart_sups[0].name} or #{obj_sups[0].name}"
985
+ trace :query, "ambiguous query, could be over #{counterpart_sups[0].name} or #{obj_sups[0].name}"
983
986
  if !roles.detect{|r| r.object_type == counterpart_sups[0]} and roles.detect{|r| r.object_type == obj_sups[0]}
984
- debug :query, "discounting #{counterpart_sups[0].name} in favour of direct objectification"
987
+ trace :query, "discounting #{counterpart_sups[0].name} in favour of direct objectification"
985
988
  counterpart_sups = []
986
989
  end
987
990
  end
@@ -9,10 +9,12 @@ module ActiveFacts
9
9
 
10
10
  class AgentName < String
11
11
  value_type
12
+ one_to_one :agent # See Agent.agent_name
12
13
  end
13
14
 
14
15
  class AggregateCode < String
15
16
  value_type :length => 32
17
+ one_to_one :aggregate # See Aggregate.aggregate_code
16
18
  end
17
19
 
18
20
  class Assimilation < String
@@ -60,10 +62,15 @@ module ActiveFacts
60
62
 
61
63
  class Guid < ::Guid
62
64
  value_type
65
+ one_to_one :alternative_set # See AlternativeSet.guid
66
+ one_to_one :concept # See Concept.guid
67
+ one_to_one :role_sequence # See RoleSequence.guid
68
+ one_to_one :shape # See Shape.guid
63
69
  end
64
70
 
65
71
  class ImplicationRuleName < String
66
72
  value_type
73
+ one_to_one :implication_rule # See ImplicationRule.implication_rule_name
67
74
  end
68
75
 
69
76
  class Length < UnsignedInteger
@@ -76,6 +83,9 @@ module ActiveFacts
76
83
 
77
84
  class Name < String
78
85
  value_type :length => 64
86
+ one_to_one :plural_named_unit, :class => "Unit", :counterpart => :plural_name # See Unit.plural_name
87
+ one_to_one :unit # See Unit.name
88
+ one_to_one :vocabulary # See Vocabulary.name
79
89
  end
80
90
 
81
91
  class Numerator < Decimal
@@ -295,7 +305,7 @@ module ActiveFacts
295
305
  maybe :is_fundamental
296
306
  one_to_one :name, :mandatory => true # See Name.unit
297
307
  has_one :offset # See Offset.all_unit
298
- one_to_one :plural_name, :class => Name # See Name.unit_as_plural_name
308
+ one_to_one :plural_name, :class => Name, :counterpart => :plural_named_unit # See Name.plural_named_unit
299
309
  has_one :vocabulary, :mandatory => true # See Vocabulary.all_unit
300
310
  end
301
311
 
@@ -139,10 +139,10 @@ module ActiveFacts
139
139
  @player_by_role_ref[ref] or ref.play && @player_by_play[ref.play]
140
140
  end
141
141
  if existing_player
142
- debug :player, "Using existing player for #{ref.role.object_type.name} #{ref.respond_to?(:role_sequence) && ref.role_sequence.all_reading.size > 0 ? ' in reading' : ''}in '#{ref.role.fact_type.default_reading}'"
142
+ trace :player, "Using existing player for #{ref.role.object_type.name} #{ref.respond_to?(:role_sequence) && ref.role_sequence.all_reading.size > 0 ? ' in reading' : ''}in '#{ref.role.fact_type.default_reading}'"
143
143
  return existing_player
144
144
  else
145
- debug :player, "Adding new player for #{ref.role.object_type.name} #{ref.respond_to?(:role_sequence) && ref.role_sequence.all_reading.size > 0 ? ' in reading' : ''}in '#{ref.role.fact_type.default_reading}'"
145
+ trace :player, "Adding new player for #{ref.role.object_type.name} #{ref.respond_to?(:role_sequence) && ref.role_sequence.all_reading.size > 0 ? ' in reading' : ''}in '#{ref.role.fact_type.default_reading}'"
146
146
  p = Player.new(ref.role.object_type)
147
147
  @players.push(p)
148
148
  p
@@ -162,11 +162,11 @@ module ActiveFacts
162
162
 
163
163
  # Add a RoleRef to an existing Player
164
164
  def add_role_player player, role_ref
165
- #debug :subscript, "Adding role_ref #{role_ref.object_id} to player #{player.object_id}"
165
+ #trace :subscript, "Adding role_ref #{role_ref.object_id} to player #{player.object_id}"
166
166
  if jr = role_ref.play
167
167
  add_play(player, jr)
168
168
  elsif !player.role_refs.include?(role_ref)
169
- debug :subscript, "Adding reference to player #{player.object_id} for #{role_ref.role.object_type.name} in #{role_ref.role_sequence.describe} with #{role_ref.role_sequence.all_reading.size} readings"
169
+ trace :subscript, "Adding reference to player #{player.object_id} for #{role_ref.role.object_type.name} in #{role_ref.role_sequence.describe} with #{role_ref.role_sequence.all_reading.size} readings"
170
170
  player.role_refs.push(role_ref)
171
171
  @player_by_role_ref[role_ref] = player
172
172
  end
@@ -222,9 +222,9 @@ module ActiveFacts
222
222
  end
223
223
  p = existing_players[0] || player(plays[0])
224
224
  debugger if plays.detect{|jr| jr.role.object_type != p.object_type }
225
- debug :subscript, "roles are playes of #{p.describe}" do
225
+ trace :subscript, "roles are playes of #{p.describe}" do
226
226
  plays.each do |play|
227
- debug :subscript, "#{play.describe}" do
227
+ trace :subscript, "#{play.describe}" do
228
228
  add_play p, play
229
229
  end
230
230
  end
@@ -244,7 +244,7 @@ module ActiveFacts
244
244
  end
245
245
  p = existing_players[0] || player(role_refs[0])
246
246
 
247
- debug :subscript, "#{existing_players[0] ? 'Adding to existing' : 'Creating new'} player for #{role_refs.map{|rr| rr.role.object_type.name}.uniq*', '}" do
247
+ trace :subscript, "#{existing_players[0] ? 'Adding to existing' : 'Creating new'} player for #{role_refs.map{|rr| rr.role.object_type.name}.uniq*', '}" do
248
248
  role_refs.each do |rr|
249
249
  unless p.object_type == rr.role.object_type
250
250
  # This happens in SubtypePI because uniqueness constraint is built without its implicit subtyping step.
@@ -275,10 +275,10 @@ module ActiveFacts
275
275
  p.role_adjuncts(matching) == player.role_adjuncts(matching)
276
276
  end
277
277
  if dups.size == 1
278
- debug :subscript, "No subscript needed for #{object_type.name}"
278
+ trace :subscript, "No subscript needed for #{object_type.name}"
279
279
  next
280
280
  end
281
- debug :subscript, "Applying subscripts to #{dups.size} occurrences of #{object_type.name}" do
281
+ trace :subscript, "Applying subscripts to #{dups.size} occurrences of #{object_type.name}" do
282
282
  s = 0
283
283
  dups.
284
284
  sort_by{|p| # Guarantee stable numbering
@@ -350,7 +350,7 @@ module ActiveFacts
350
350
  prrs = fact_type.preferred_reading.role_sequence.all_role_ref
351
351
  residual_roles = fact_type.all_role.select{|r| !@role_refs.detect{|rr| rr.role == r} }
352
352
  residual_roles.each do |role|
353
- debug :subscript, "Adding residual role for #{role.object_type.name} (in #{fact_type.default_reading}) not covered in role sequence"
353
+ trace :subscript, "Adding residual role for #{role.object_type.name} (in #{fact_type.default_reading}) not covered in role sequence"
354
354
  preferred_role_ref = prrs.detect{|rr| rr.role == role}
355
355
  if p = @player_by_role_ref[preferred_role_ref] and !p.role_refs.include?(preferred_role_ref)
356
356
  raise "Adding DUPLICATE residual role for #{role.object_type.name}"
@@ -361,11 +361,11 @@ module ActiveFacts
361
361
  end
362
362
 
363
363
  def prepare_query_players query
364
- debug :subscript, "Indexing roles of fact types in #{query.all_step.size} steps" do
364
+ trace :subscript, "Indexing roles of fact types in #{query.all_step.size} steps" do
365
365
  steps = []
366
366
  # Register all references to each variable as being for the same player:
367
367
  query.all_variable.sort_by{|jn| jn.ordinal}.each do |variable|
368
- debug :subscript, "Adding Roles of #{variable.describe}" do
368
+ trace :subscript, "Adding Roles of #{variable.describe}" do
369
369
  plays_have_same_player(variable.all_play.to_a)
370
370
  steps = steps | variable.all_step
371
371
  end
@@ -388,11 +388,11 @@ module ActiveFacts
388
388
  #steps.map{|js|js.fact_type}.uniq.each do |fact_type|
389
389
  next if fact_type.is_a?(ActiveFacts::Metamodel::LinkFactType)
390
390
 
391
- debug :subscript, "Residual roles in '#{fact_type.default_reading}' are" do
391
+ trace :subscript, "Residual roles in '#{fact_type.default_reading}' are" do
392
392
  prrs = fact_type.preferred_reading.role_sequence.all_role_ref
393
393
  residual_roles = fact_type.all_role.select{|r| !r.all_role_ref.detect{|rr| rr.variable && rr.variable.query == query} }
394
394
  residual_roles.each do |r|
395
- debug :subscript, "Adding residual role for #{r.object_type.name} (in #{fact_type.default_reading}) not covered in query"
395
+ trace :subscript, "Adding residual role for #{r.object_type.name} (in #{fact_type.default_reading}) not covered in query"
396
396
  preferred_role_ref = prrs.detect{|rr| rr.role == r}
397
397
  if p = @player_by_role_ref[preferred_role_ref] and !p.role_refs.include?(preferred_role_ref)
398
398
  raise "Adding DUPLICATE residual role for #{r.object_type.name} not covered in query"
@@ -433,7 +433,7 @@ module ActiveFacts
433
433
  reading.role_sequence.all_role_ref.each do |rr|
434
434
  next unless player = @player_by_role_ref[rr]
435
435
  next unless subscript = player.subscript
436
- debug :subscript, "Need to apply subscript #{subscript} to #{rr.role.object_type.name}"
436
+ trace :subscript, "Need to apply subscript #{subscript} to #{rr.role.object_type.name}"
437
437
  end
438
438
  player_by_role = {}
439
439
  @player_by_role_ref.keys.each{|rr| player_by_role[rr.role] = @player_by_role_ref[rr] if rr.role.fact_type == fact_type }
@@ -454,7 +454,7 @@ module ActiveFacts
454
454
  plays = ([step.input_play, step.output_play]+step.all_incidental_play.to_a).compact
455
455
  variable_by_role = plays.inject({}) { |h, play| h[play.role] = play.variable; h }
456
456
  end
457
- debug :subscript, "expanding '#{text}' with #{role_sequence.describe}" do
457
+ trace :subscript, "expanding '#{text}' with #{role_sequence.describe}" do
458
458
  text.gsub(/\{(\d)\}/) do
459
459
  role_ref = rrs[$1.to_i]
460
460
  # REVISIT: We may need to use the step's role_refs to expand the role players here, not the reading's one (extra adjectives?)
@@ -471,7 +471,7 @@ module ActiveFacts
471
471
  def subscripted_player role_ref, subscript = nil, play_name = nil, value = nil
472
472
  prr = @player_by_role_ref[role_ref]
473
473
  subscript ||= prr.subscript if prr
474
- debug :subscript, "Need to apply subscript #{subscript} to #{role_ref.role.object_type.name}" if subscript
474
+ trace :subscript, "Need to apply subscript #{subscript} to #{role_ref.role.object_type.name}" if subscript
475
475
  object_type = role_ref.role.object_type
476
476
  (play_name ||
477
477
  [
@@ -532,19 +532,19 @@ module ActiveFacts
532
532
  # so just use any step involving this node, or just any step.
533
533
  if next_steps
534
534
  if next_step = next_steps.detect { |ns| !ns.is_objectification_step }
535
- debug :query, "Chose new non-objectification step: #{next_step.describe}"
535
+ trace :query, "Chose new non-objectification step: #{next_step.describe}"
536
536
  return next_step
537
537
  end
538
538
  end
539
539
 
540
540
  if next_step = @steps.detect { |ns| !ns.is_objectification_step }
541
- debug :query, "Chose random non-objectification step: #{next_step.describe}"
541
+ trace :query, "Chose random non-objectification step: #{next_step.describe}"
542
542
  return next_step
543
543
  end
544
544
 
545
545
  next_step = @steps[0]
546
546
  if next_step
547
- debug :query, "Chose new random step from #{steps.size}: #{next_step.describe}"
547
+ trace :query, "Chose new random step from #{steps.size}: #{next_step.describe}"
548
548
  if next_step.is_objectification_step
549
549
  # if this objectification plays any roles (other than its FT roles) in remaining steps, use one of those first:
550
550
  fact_type = next_step.fact_type.implying_role.fact_type
@@ -590,7 +590,7 @@ module ActiveFacts
590
590
  end
591
591
  next_reading
592
592
  end
593
- debug :query, "#{next_reading ? "'"+next_reading.expand+"'" : "No reading"} contracts against last node '#{next_node.object_type.name}'"
593
+ trace :query, "#{next_reading ? "'"+next_reading.expand+"'" : "No reading"} contracts against last node '#{next_node.object_type.name}'"
594
594
  return [next_step, next_reading]
595
595
  end
596
596
 
@@ -621,7 +621,7 @@ module ActiveFacts
621
621
  js.input_play.variable.object_type == object_type || js.output_play.variable.object_type == object_type
622
622
  }
623
623
  steps << other_step
624
- debug :query, "Emitting objectification step allows deleting #{other_step.describe}"
624
+ trace :query, "Emitting objectification step allows deleting #{other_step.describe}"
625
625
  step_completed(other_step)
626
626
  end
627
627
 
@@ -658,12 +658,12 @@ module ActiveFacts
658
658
  exit_node = @variables.detect{|jn| jn.all_play.detect{|jr| jr.role == last_role_ref.role}}
659
659
  exit_step = nil
660
660
 
661
- debug :query, "Stepping over an objectification to #{exit_node.object_type.name} requires eliding the other implied steps" do
661
+ trace :query, "Stepping over an objectification to #{exit_node.object_type.name} requires eliding the other implied steps" do
662
662
  count = 0
663
663
  while other_step =
664
664
  @steps.
665
665
  detect{|js|
666
- debug :query, "Considering step '#{js.fact_type.default_reading}'"
666
+ trace :query, "Considering step '#{js.fact_type.default_reading}'"
667
667
  next unless js.is_objectification_step
668
668
 
669
669
  # REVISIT: This test is too weak: We need to ensure that the same variables are involved, not just the same object types:
@@ -671,7 +671,7 @@ module ActiveFacts
671
671
  exit_step = js if js.output_play.variable == exit_node
672
672
  true
673
673
  }
674
- debug :query, "Emitting objectified FT allows deleting #{other_step.describe}"
674
+ trace :query, "Emitting objectified FT allows deleting #{other_step.describe}"
675
675
  step_completed(other_step)
676
676
  # raise "The objectification of '#{fact_type.default_reading}' should not cause the deletion of more than #{fact_type.all_role.size} other steps" if (count += 1) > fact_type.all_role.size
677
677
  end
@@ -685,12 +685,12 @@ module ActiveFacts
685
685
  readings = ''
686
686
  next_node = @role_refs[0].play.variable # Choose a place to start
687
687
  last_is_contractable = false
688
- debug :query, "Variables are #{@variables.map{|jn| jn.describe }.inspect}, Steps are #{@steps.map{|js| js.describe }.inspect}" do
688
+ trace :query, "Variables are #{@variables.map{|jn| jn.describe }.inspect}, Steps are #{@steps.map{|js| js.describe }.inspect}" do
689
689
  until @steps.empty?
690
690
  next_reading = nil
691
691
  # Choose amonst all remaining steps we can take from the next node, if any
692
692
  next_steps = @steps_by_variable[next_node]
693
- debug :query, "Next Steps from #{next_node.describe} are #{(next_steps||[]).map{|js| js.describe }.inspect}"
693
+ trace :query, "Next Steps from #{next_node.describe} are #{(next_steps||[]).map{|js| js.describe }.inspect}"
694
694
 
695
695
  # See if we can find a next step that contracts against the last (if any):
696
696
  next_step = nil
@@ -699,7 +699,7 @@ module ActiveFacts
699
699
  end
700
700
 
701
701
  if next_step
702
- debug :query, "Chose #{next_step.describe} because it's contractable against last node #{next_node.object_type.name} using #{next_reading.expand}"
702
+ trace :query, "Chose #{next_step.describe} because it's contractable against last node #{next_node.object_type.name} using #{next_reading.expand}"
703
703
 
704
704
  player_by_role =
705
705
  next_step.all_play.inject({}) {|h, jr| h[jr.role] = @player_by_play[jr]; h }