activefacts 1.0.2 → 1.1.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 (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 }