activefacts 0.8.18 → 1.0.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 (42) hide show
  1. checksums.yaml +8 -8
  2. data/Rakefile +0 -8
  3. data/examples/CQL/CompanyDirectorEmployee.cql +12 -8
  4. data/examples/CQL/Metamodel.cql +40 -24
  5. data/examples/CQL/OilSupply.cql +10 -8
  6. data/examples/CQL/unit.cql +52 -51
  7. data/lib/activefacts/cql/LexicalRules.treetop +1 -1
  8. data/lib/activefacts/cql/compiler.rb +1 -1
  9. data/lib/activefacts/cql/compiler/clause.rb +16 -24
  10. data/lib/activefacts/cql/compiler/constraint.rb +4 -4
  11. data/lib/activefacts/cql/compiler/entity_type.rb +16 -16
  12. data/lib/activefacts/cql/compiler/expression.rb +3 -3
  13. data/lib/activefacts/cql/compiler/fact.rb +1 -1
  14. data/lib/activefacts/cql/compiler/fact_type.rb +14 -4
  15. data/lib/activefacts/cql/compiler/shared.rb +1 -1
  16. data/lib/activefacts/cql/compiler/value_type.rb +2 -2
  17. data/lib/activefacts/generate/cql.rb +10 -34
  18. data/lib/activefacts/generate/helpers/oo.rb +10 -6
  19. data/lib/activefacts/generate/helpers/ordered.rb +32 -6
  20. data/lib/activefacts/generate/json.rb +2 -2
  21. data/lib/activefacts/generate/ruby.rb +7 -15
  22. data/lib/activefacts/generate/transform/surrogate.rb +7 -7
  23. data/lib/activefacts/input/orm.rb +23 -26
  24. data/lib/activefacts/persistence/index.rb +1 -1
  25. data/lib/activefacts/persistence/reference.rb +5 -2
  26. data/lib/activefacts/version.rb +3 -3
  27. data/lib/activefacts/vocabulary/extensions.rb +59 -19
  28. data/lib/activefacts/vocabulary/metamodel.rb +30 -14
  29. data/spec/cql/parser/bad_literals_spec.rb +1 -1
  30. data/spec/cql/parser/expressions_spec.rb +1 -1
  31. data/spec/cql_dm_spec.rb +15 -0
  32. data/spec/cql_mysql_spec.rb +1 -1
  33. data/spec/cqldump_spec.rb +12 -12
  34. data/spec/norma_cql_spec.rb +0 -1
  35. data/spec/norma_ruby_sql_spec.rb +3 -2
  36. data/spec/norma_tables_spec.rb +1 -1
  37. metadata +78 -127
  38. data/examples/CQL/JoinEquality.cql +0 -35
  39. data/examples/CQL/MonthInSeason.cql +0 -23
  40. data/examples/CQL/Moon.cql +0 -23
  41. data/examples/CQL/SubtypePI.cql +0 -31
  42. data/examples/CQL/Tests.Test5.Load.cql +0 -38
@@ -158,7 +158,7 @@ module ActiveFacts
158
158
  end
159
159
 
160
160
  rule alpha
161
- [[:alpha:]]
161
+ [[:alpha:]_]
162
162
  end
163
163
 
164
164
  rule alphanumeric
@@ -96,7 +96,7 @@ module ActiveFacts
96
96
  saved_string = @string
97
97
  saved_input_length = @input_length
98
98
  old_filename = @filename
99
- @filename = file+'.cql' # REVISIT: Use File.dirname(@filename)+@filename ?
99
+ @filename = File.dirname(old_filename)+'/'+file+'.cql'
100
100
 
101
101
  # REVISIT: Save and use another @vocabulary for this file?
102
102
  File.open(@filename) do |f|
@@ -232,26 +232,13 @@ module ActiveFacts
232
232
  candidate_fact_types =
233
233
  start_obj.map do |related_type|
234
234
  related_type.all_role.select do |role|
235
- all_roles = role.fact_type.all_role
236
- next if all_roles.size != players.size # Wrong number of players
235
+ # next if role.fact_type.all_reading.size == 0
237
236
  next if role.fact_type.is_a?(ActiveFacts::Metamodel::LinkFactType)
237
+ next if role.fact_type.all_role.size != players.size # Wrong number of players
238
238
 
239
- all_players = all_roles.map{|r| r.object_type} # All the players of this candidate fact type
240
-
241
- next if player_related_types[1..-1]. # We know the first player is compatible, check the rest
242
- detect do |player_types| # Make sure that there remains a compatible player
243
- # player_types is an array of the types compatible with the Nth player
244
- compatible_player = nil
245
- all_players.each_with_index do |p, i|
246
- if player_types.include?(p)
247
- compatible_player = p
248
- all_players.delete_at(i)
249
- break
250
- end
251
- end
252
- !compatible_player
253
- end
254
-
239
+ compatible_readings = role.fact_type.compatible_readings(player_related_types)
240
+ next unless compatible_readings.size > 0
241
+ debug :matching_fails, "These readings are compatible: #{compatible_readings.map(&:expand).inspect}"
255
242
  true
256
243
  end.
257
244
  map{ |role| role.fact_type}
@@ -419,9 +406,14 @@ module ActiveFacts
419
406
  if la = role_ref.leading_adjective and !la.empty?
420
407
  # The leading adjectives must match, one way or another
421
408
  la = la.split(/\s+/)
422
- # We may have hyphenated adjectives. Break them up to check:
423
- iw = intervening_words.map{|w| w.split(/-/)}.flatten
424
- return nil unless la[0,iw.size] == iw
409
+ if (la[0, intervening_words.size] == intervening_words) # Exact match
410
+ iw = intervening_words
411
+ else
412
+ # We may have hyphenated adjectives. Break them up to check:
413
+ iw = intervening_words.map{|w| w.split(/-/)}.flatten
414
+ return nil unless la[0,iw.size] == iw
415
+ end
416
+
425
417
  # Any intervening_words matched, see what remains
426
418
  la.slice!(0, iw.size)
427
419
 
@@ -593,7 +585,7 @@ module ActiveFacts
593
585
  debug :matching, "Making new fact type for #{@phrases.inspect}" do
594
586
  @phrases.each do |phrase|
595
587
  next unless phrase.respond_to?(:player)
596
- phrase.role = vocabulary.constellation.Role(fact_type, fact_type.all_role.size, :object_type => phrase.player, :guid => :new)
588
+ phrase.role = vocabulary.constellation.Role(fact_type, fact_type.all_role.size, :object_type => phrase.player, :concept => :new)
597
589
  phrase.role.role_name = phrase.role_name if phrase.role_name && phrase.role_name.is_a?(String)
598
590
  end
599
591
  end
@@ -801,7 +793,7 @@ module ActiveFacts
801
793
  @negated = negated
802
794
  end
803
795
 
804
- def to_s
796
+ def inspect
805
797
  'side-effects are [' +
806
798
  @role_side_effects.map{|r| r.to_s}*', ' +
807
799
  ']' +
@@ -1035,7 +1027,7 @@ module ActiveFacts
1035
1027
  :max_frequency => @quantifier.max,
1036
1028
  :min_frequency => @quantifier.min
1037
1029
  )
1038
- debug :constraint, "Made new embedded PC GUID=#{constraint.guid} min=#{@quantifier.min.inspect} max=#{@quantifier.max.inspect} over #{(e = fact_type.entity_type) ? e.name : role_sequence.describe} in #{fact_type.describe}"
1030
+ debug :constraint, "Made new embedded PC GUID=#{constraint.concept.guid} min=#{@quantifier.min.inspect} max=#{@quantifier.max.inspect} over #{(e = fact_type.entity_type) ? e.name : role_sequence.describe} in #{fact_type.describe}"
1039
1031
  @quantifier.enforcement.compile(constellation, constraint) if @quantifier.enforcement
1040
1032
  @embedded_presence_constraint = constraint
1041
1033
  end
@@ -28,7 +28,7 @@ module ActiveFacts
28
28
  :context_note_kind => @context_kind,
29
29
  :discussion => @discussion
30
30
  )
31
- context_note.relevant_concept = target
31
+ context_note.relevant_concept = target.concept
32
32
  if @agreed_date || @agreed_agents
33
33
  agreement = constellation.Agreement(context_note)
34
34
  agreement.date = @agreed_date if @agreed_date
@@ -226,7 +226,7 @@ module ActiveFacts
226
226
  :is_mandatory => @quantifier.min && @quantifier.min > 0
227
227
  )
228
228
  @enforcement.compile(@constellation, @constraint) if @enforcement
229
- debug :constraint, "Made new PC GUID=#{@constraint.guid} min=#{@quantifier.min.inspect} max=#{@quantifier.max.inspect} over #{role_sequence.describe}"
229
+ debug :constraint, "Made new PC GUID=#{@constraint.concept.guid} min=#{@quantifier.min.inspect} max=#{@quantifier.max.inspect} over #{role_sequence.describe}"
230
230
  super
231
231
  end
232
232
 
@@ -461,7 +461,7 @@ module ActiveFacts
461
461
  raise "ambiguous #{@rings*' '} ring constraint, consider #{role_pairs.map{|rp| "#{rp[0].inspect}<->#{rp[1].inspect}"}*', '}"
462
462
  end
463
463
  if role_pairs.size == 0
464
- raise "No matching role pair found for #{@rings*' '} ring constraint"
464
+ raise "No matching role pair found for #{@rings*' '} ring constraint over #{role_refs.map(&:role).map(&:object_type).map(&:name).inspect}"
465
465
  end
466
466
 
467
467
  rp = role_pairs[0]
@@ -483,7 +483,7 @@ module ActiveFacts
483
483
  :ring_type => ring_type
484
484
  )
485
485
 
486
- debug :constraint, "Added #{@constraint.verbalise} #{@constraint.class.roles.keys.map{|k|"#{k} => "+@constraint.send(k).verbalise}*", "}"
486
+ debug :constraint, "Added #{@constraint.verbalise}"
487
487
  super
488
488
  end
489
489
 
@@ -30,7 +30,7 @@ module ActiveFacts
30
30
 
31
31
  def compile
32
32
  @entity_type = @vocabulary.valid_entity_type_name(@name) ||
33
- @constellation.EntityType(@vocabulary, @name, :guid => :new)
33
+ @constellation.EntityType(@vocabulary, @name, :concept => :new)
34
34
  @entity_type.is_independent = true if (@pragmas.include? 'independent')
35
35
 
36
36
  # REVISIT: CQL needs a way to indicate whether subtype migration can occur.
@@ -122,7 +122,7 @@ module ActiveFacts
122
122
  if (pc)
123
123
  pc.is_preferred_identifier = true
124
124
  pc.name = "#{@entity_type.name}PK" unless pc.name
125
- debug "Existing PC #{pc.verbalise} is now PK for #{@entity_type.name} #{pc.class.roles.keys.map{|k|"#{k} => "+pc.send(k).verbalise}*", "}"
125
+ debug "Existing PC #{pc.verbalise} is now PK for #{@entity_type.name}"
126
126
  else
127
127
  # Add a unique constraint over all identifying roles
128
128
  pc = @constellation.PresenceConstraint(
@@ -135,7 +135,7 @@ module ActiveFacts
135
135
  #:is_mandatory => true,
136
136
  #:min_frequency => 1,
137
137
  )
138
- debug :constraint, "Made new preferred PC GUID=#{pc.guid} min=nil max=1 over #{role_sequence.describe}"
138
+ debug :constraint, "Made new preferred PC GUID=#{pc.concept.guid} min=nil max=1 over #{role_sequence.describe}"
139
139
  end
140
140
  end
141
141
 
@@ -220,7 +220,7 @@ module ActiveFacts
220
220
  :is_preferred_identifier => false, # We only get here when there is a reference mode on the entity type
221
221
  :max_frequency => 1
222
222
  )
223
- debug :constraint, "Made new objectification PC GUID=#{pc.guid} min=nil max=1 over #{fact_type.preferred_reading.role_sequence.describe}"
223
+ debug :constraint, "Made new objectification PC GUID=#{pc.concept.guid} min=nil max=1 over #{fact_type.preferred_reading.role_sequence.describe}"
224
224
  end
225
225
 
226
226
  @fact_type = @entity_type.fact_type = fact_type
@@ -231,7 +231,7 @@ module ActiveFacts
231
231
  def add_supertype(supertype_name, not_identifying)
232
232
  debug :supertype, "Adding #{not_identifying ? '' : 'identifying '}supertype #{supertype_name} to #{@entity_type.name}" do
233
233
  supertype = @vocabulary.valid_entity_type_name(supertype_name) ||
234
- @constellation.EntityType(@vocabulary, supertype_name, :guid => :new) # Should always already exist
234
+ @constellation.EntityType(@vocabulary, supertype_name, :concept => :new) # Should always already exist
235
235
 
236
236
  # Did we already know about this supertyping?
237
237
  return if @entity_type.all_type_inheritance_as_subtype.detect{|ti| ti.supertype == supertype}
@@ -239,15 +239,15 @@ module ActiveFacts
239
239
  # By default, the first supertype identifies this entity type
240
240
  is_identifying_supertype = !not_identifying && @entity_type.all_type_inheritance_as_subtype.size == 0
241
241
 
242
- inheritance_fact = @constellation.TypeInheritance(@entity_type, supertype, :guid => :new)
242
+ inheritance_fact = @constellation.TypeInheritance(@entity_type, supertype, :concept => :new)
243
243
 
244
244
  assimilations = @pragmas.select { |p| ['absorbed', 'separate', 'partitioned'].include? p}
245
245
  raise "Conflicting assimilation pragmas #{assimilations*', '}" if assimilations.size > 1
246
246
  inheritance_fact.assimilation = assimilations[0]
247
247
 
248
248
  # Create a reading:
249
- sub_role = @constellation.Role(inheritance_fact, 0, :object_type => @entity_type, :guid => :new)
250
- super_role = @constellation.Role(inheritance_fact, 1, :object_type => supertype, :guid => :new)
249
+ sub_role = @constellation.Role(inheritance_fact, 0, :object_type => @entity_type, :concept => :new)
250
+ super_role = @constellation.Role(inheritance_fact, 1, :object_type => supertype, :concept => :new)
251
251
 
252
252
  rs = @constellation.RoleSequence(:new)
253
253
  @constellation.RoleRef(rs, 0, :role => sub_role)
@@ -275,7 +275,7 @@ module ActiveFacts
275
275
  pc1.min_frequency = 1
276
276
  pc1.max_frequency = 1
277
277
  pc1.is_preferred_identifier = false
278
- debug :constraint, "Made new subtype PC GUID=#{pc1.guid} min=1 max=1 over #{p1rs.describe}"
278
+ debug :constraint, "Made new subtype PC GUID=#{pc1.concept.guid} min=1 max=1 over #{p1rs.describe}"
279
279
 
280
280
  p2rs = @constellation.RoleSequence(:new)
281
281
  constellation.RoleRef(p2rs, 0).role = super_role
@@ -288,7 +288,7 @@ module ActiveFacts
288
288
  # The supertype role often identifies the subtype:
289
289
  pc2.is_preferred_identifier = inheritance_fact.provides_identification
290
290
  debug :supertype, "identification of #{@entity_type.name} via supertype #{supertype.name} was #{inheritance_fact.provides_identification ? '' : 'not '}added"
291
- debug :constraint, "Made new supertype PC GUID=#{pc2.guid} min=1 max=1 over #{p2rs.describe}"
291
+ debug :constraint, "Made new supertype PC GUID=#{pc2.concept.guid} min=1 max=1 over #{p2rs.describe}"
292
292
  end
293
293
  end
294
294
 
@@ -301,8 +301,8 @@ module ActiveFacts
301
301
  unless vt = @vocabulary.valid_object_type_name(vt_name) or
302
302
  vt = @vocabulary.valid_object_type_name(vt_name = "#{name} #{mode}")
303
303
  base_vt = @vocabulary.valid_value_type_name(mode) ||
304
- @constellation.ValueType(@vocabulary, mode, :guid => :new)
305
- vt = @constellation.ValueType(@vocabulary, vt_name, :supertype => base_vt, :guid => :new)
304
+ @constellation.ValueType(@vocabulary, mode, :concept => :new)
305
+ vt = @constellation.ValueType(@vocabulary, vt_name, :supertype => base_vt, :concept => :new)
306
306
  if parameters
307
307
  length, scale = *parameters
308
308
  vt.length = length if length
@@ -335,8 +335,8 @@ module ActiveFacts
335
335
  unless fact_type
336
336
  fact_type = @constellation.FactType(:new)
337
337
  fact_types << fact_type
338
- entity_role = @constellation.Role(fact_type, 0, :object_type => @entity_type, :guid => :new)
339
- identifying_role = @constellation.Role(fact_type, 1, :object_type => identifying_type, :guid => :new)
338
+ entity_role = @constellation.Role(fact_type, 0, :object_type => @entity_type, :concept => :new)
339
+ identifying_role = @constellation.Role(fact_type, 1, :object_type => identifying_type, :concept => :new)
340
340
  end
341
341
  @identification[0].role = identifying_role
342
342
 
@@ -403,7 +403,7 @@ module ActiveFacts
403
403
  :is_preferred_identifier => false,
404
404
  :is_mandatory => true
405
405
  )
406
- debug :constraint, "Made new refmode PC GUID=#{constraint.guid} min=1 max=1 over #{rs0.describe}"
406
+ debug :constraint, "Made new refmode PC GUID=#{constraint.concept.guid} min=1 max=1 over #{rs0.describe}"
407
407
  else
408
408
  debug :mode, "Using existing EntityType PresenceConstraint"
409
409
  end
@@ -431,7 +431,7 @@ module ActiveFacts
431
431
  :is_preferred_identifier => true,
432
432
  :is_mandatory => false
433
433
  )
434
- debug :constraint, "Made new refmode ValueType PC GUID=#{constraint.guid} min=0 max=1 over #{rs1.describe}"
434
+ debug :constraint, "Made new refmode ValueType PC GUID=#{constraint.concept.guid} min=0 max=1 over #{rs1.describe}"
435
435
  else
436
436
  debug :mode, "Marking existing ValueType PresenceConstraint as preferred"
437
437
  rs1.all_presence_constraint.single.is_preferred_identifier = true
@@ -93,7 +93,7 @@ module ActiveFacts
93
93
  vocabulary = context.vocabulary
94
94
  constellation = vocabulary.constellation
95
95
  vocabulary.valid_value_type_name(name) ||
96
- constellation.ValueType(vocabulary, name, :guid => :new)
96
+ constellation.ValueType(vocabulary, name, :concept => :new)
97
97
  end
98
98
 
99
99
  def is_naked_object_type
@@ -194,7 +194,7 @@ module ActiveFacts
194
194
  v = context.vocabulary
195
195
  @boolean ||=
196
196
  v.constellation.ValueType[[[v.name], 'Boolean']] ||
197
- v.constellation.ValueType(v, 'Boolean', :guid => :new)
197
+ v.constellation.ValueType(v, 'Boolean', :concept => :new)
198
198
  @player = @boolean
199
199
  end
200
200
  end
@@ -337,7 +337,7 @@ module ActiveFacts
337
337
  # REVISIT: Calculate the units of the result from the units in @divisor
338
338
  # REVISIT: Do we want integer division?
339
339
  v = context.vocabulary
340
- @player = v.constellation.ValueType(v, 'Real', :guid => :new)
340
+ @player = v.constellation.ValueType(v, 'Real', :concept => :new)
341
341
  end
342
342
  end
343
343
 
@@ -10,7 +10,7 @@ module ActiveFacts
10
10
 
11
11
  def compile
12
12
  @population = @constellation.Population[[@vocabulary.identifying_role_values, @population_name]] ||
13
- @constellation.Population(@vocabulary, @population_name, :guid => :new)
13
+ @constellation.Population(@vocabulary, @population_name, :concept => :new)
14
14
 
15
15
  @context = CompilationContext.new(@vocabulary)
16
16
  @context.bind @clauses
@@ -97,7 +97,7 @@ module ActiveFacts
97
97
  if @name
98
98
  entity_type = @vocabulary.valid_entity_type_name(@name)
99
99
  raise "You can't objectify #{@name}, it already exists" if entity_type
100
- @entity_type = @constellation.EntityType(@vocabulary, @name, :fact_type => @fact_type, :guid => :new)
100
+ @entity_type = @constellation.EntityType(@vocabulary, @name, :fact_type => @fact_type, :concept => :new)
101
101
  end
102
102
 
103
103
  prepare_roles @clauses
@@ -286,15 +286,23 @@ module ActiveFacts
286
286
  debug :constraint, "Need to check #{@fact_type.default_reading.inspect} for a uniqueness constraint"
287
287
  fact_type.check_and_add_spanning_uniqueness_constraint = proc do
288
288
  debug :constraint, "Checking #{@fact_type.default_reading.inspect} for a uniqueness constraint"
289
- if !@fact_type.all_role.
289
+ existing_pc = nil
290
+ found = @fact_type.all_role.
290
291
  detect do |role|
291
292
  role.all_role_ref.detect do |rr|
292
293
  # This RoleSequence, to be relevant, must only reference roles of this fact type
293
294
  rr.role_sequence.all_role_ref.all? {|rr2| rr2.role.fact_type == @fact_type} and
294
295
  # The RoleSequence must have at least one uniqueness constraint
295
- rr.role_sequence.all_presence_constraint.detect{|pc| pc.max_frequency == 1}
296
+ rr.role_sequence.all_presence_constraint.detect do |pc|
297
+ if pc.max_frequency == 1
298
+ existing_pc = pc
299
+ end
300
+ end
296
301
  end
297
302
  end
303
+ true # A place for a breakpoint
304
+
305
+ if !found
298
306
  # There's no existing uniqueness constraint over the roles of this fact type. Add one
299
307
  pc = @constellation.PresenceConstraint(
300
308
  :new,
@@ -304,7 +312,9 @@ module ActiveFacts
304
312
  :max_frequency => 1,
305
313
  :is_preferred_identifier => true # (prefer || !!@fact_type.entity_type)
306
314
  )
307
- debug :constraint, "Made new fact type implicit PC GUID=#{pc.guid} #{pc.name} min=nil max=1 over #{rs.describe}"
315
+ debug :constraint, "Made new fact type implicit PC GUID=#{pc.concept.guid} #{pc.name} min=nil max=1 over #{rs.describe}"
316
+ elsif pc
317
+ debug :constraint, "Will rely on existing UC GUID=#{pc.concept.guid} #{pc.name} to be used as PI over #{rs.describe}"
308
318
  end
309
319
  end
310
320
  end
@@ -65,7 +65,7 @@ module ActiveFacts
65
65
 
66
66
  if !player && @allowed_forward_terms.include?(name)
67
67
  @vocabulary.valid_entity_type_name(name) # No need for the result here, just no exceptional condition
68
- player = constellation.EntityType(@vocabulary, name, :guid => :new)
68
+ player = constellation.EntityType(@vocabulary, name, :concept => :new)
69
69
  end
70
70
 
71
71
  player
@@ -104,14 +104,14 @@ module ActiveFacts
104
104
  base_type = nil
105
105
  if (@base_type_name != @name)
106
106
  unless base_type = @vocabulary.valid_value_type_name(@base_type_name)
107
- base_type = @constellation.ValueType(@vocabulary, @base_type_name, :guid => :new)
107
+ base_type = @constellation.ValueType(@vocabulary, @base_type_name, :concept => :new)
108
108
  return base_type if @base_type_name == @name
109
109
  end
110
110
  end
111
111
 
112
112
  # Create and initialise the ValueType:
113
113
  vt = @vocabulary.valid_value_type_name(@name) ||
114
- @constellation.ValueType(@vocabulary, @name, :guid => :new)
114
+ @constellation.ValueType(@vocabulary, @name, :concept => :new)
115
115
  vt.is_independent = true if (@pragmas.include? 'independent')
116
116
  vt.supertype = base_type if base_type
117
117
  vt.length = length if length
@@ -42,40 +42,15 @@ module ActiveFacts
42
42
  puts "\n"
43
43
  end
44
44
 
45
- def value_type_dump(o)
46
- # Ignore Value Types that don't do anything:
47
- return if
48
- !o.supertype &&
49
- o.all_role.size == 0 &&
50
- !o.is_independent &&
51
- !o.value_constraint &&
52
- o.all_context_note_as_relevant_concept.size == 0 &&
53
- o.all_instance.size == 0
45
+ def data_type_dump(o)
46
+ value_type_dump(o, o.name, {}) if o.all_role.size > 0
47
+ end
48
+
49
+ def value_type_dump(o, super_type_name, facets)
54
50
  # No need to dump it if the only thing it does is be a supertype; it'll be created automatically
55
51
  # return if o.all_value_type_as_supertype.size == 0
56
52
 
57
- =begin
58
- # Leave this out, pending a proper on-demand system for dumping VT's
59
- # A ValueType that is only used as a reference mode need not be emitted here.
60
- if o.all_value_type_as_supertype.size == 0 &&
61
- !o.all_role.
62
- detect do |role|
63
- (other_roles = role.fact_type.all_role.to_a-[role]).size != 1 || # Not a role in a binary FT
64
- !(object_type = other_roles[0].object_type).is_a?(ActiveFacts::Metamodel::EntityType) || # Counterpart is not an ET
65
- (pi = object_type.preferred_identifier).role_sequence.all_role_ref.size != 1 || # Entity PI has > 1 roles
66
- pi.role_sequence.all_role_ref.single.role != role # This isn't the identifying role
67
- end
68
- puts "About to skip #{o.name}"
69
- debugger
70
- return
71
- end
72
-
73
- # We'll dump the subtypes before any roles, so we don't need to dump this here.
74
- # ... except that isn't true, we won't do that so we can't skip it now
75
- #return if
76
- # o.all_value_type_as_supertype.size != 0 && # We have subtypes
77
- # o.all_role.size != 0
78
- =end
53
+ # REVISIT: A ValueType that is only used as a reference mode need not be emitted here.
79
54
 
80
55
  puts o.as_cql
81
56
  end
@@ -216,7 +191,7 @@ module ActiveFacts
216
191
  end
217
192
  (entity_type.is_independent ? ' independent' : '') +
218
193
  " identified by its #{value_residual}#{constraint_text}#{mapping_pragma(entity_type, true)}" +
219
- entity_type.all_context_note_as_relevant_concept.map do |cn|
194
+ entity_type.concept.all_context_note_as_relevant_concept.map do |cn|
220
195
  cn.verbalise
221
196
  end.join("\n") +
222
197
  (fact_readings.size > 0 ? " where\n\t" : "") +
@@ -253,7 +228,7 @@ module ActiveFacts
253
228
  (entity_type.is_independent ? ' independent' : '') +
254
229
  " identified by #{ irn*" and " }" +
255
230
  mapping_pragma(entity_type, true) +
256
- entity_type.all_context_note_as_relevant_concept.map do |cn|
231
+ entity_type.concept.all_context_note_as_relevant_concept.map do |cn|
257
232
  cn.verbalise
258
233
  end.join("\n") +
259
234
  " where\n\t"+identifying_fact_text
@@ -656,7 +631,7 @@ module ActiveFacts
656
631
  }#{
657
632
  unit && " "+unit.name
658
633
  }#{
659
- all_context_note_as_relevant_concept.map do |cn|
634
+ concept.all_context_note_as_relevant_concept.map do |cn|
660
635
  cn.verbalise
661
636
  end.join("\n")
662
637
  }#{
@@ -687,6 +662,7 @@ module ActiveFacts
687
662
  end +
688
663
 
689
664
  all_derivation_as_derived_unit.
665
+ sort_by{|d| d.base_unit.name}.
690
666
  # REVISIT: Sort base units
691
667
  # REVISIT: convert negative powers to division?
692
668
  map do |der|
@@ -97,11 +97,12 @@ module ActiveFacts
97
97
  binary_dump(role, other_role_name, other_player, role.is_mandatory, one_to_one, nil, role_name, other_role_method)
98
98
  end
99
99
 
100
- def preferred_role_name(role, is_for = nil)
101
- return "" if role.fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance)
100
+ def preferred_role_name(role, is_for = nil, &b)
101
+ b ||= proc {|names| names.map(&:downcase)*'_' } # Make snake_case by default
102
+ return b.call([]) if role.fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance)
102
103
 
103
104
  if is_for && role.fact_type.entity_type == is_for && role.fact_type.all_role.size == 1
104
- return role.object_type.name.gsub(/[- ]/,'_').snakecase
105
+ return b.call(role.object_type.name.gsub(/[- ]/,'_').split(/_/))
105
106
  end
106
107
 
107
108
  # debug "Looking for preferred_role_name of #{describe_fact_type(role.fact_type, role)}"
@@ -112,8 +113,11 @@ module ActiveFacts
112
113
 
113
114
  # Unaries are a hack, with only one role for what is effectively a binary:
114
115
  if (role.fact_type.all_role.size == 1)
115
- return (role.role_name && role.role_name.snakecase) ||
116
- reading.text.gsub(/ *\{0\} */,'').gsub(/[- ]/,'_').downcase
116
+ return b.call(
117
+ ( (role.role_name && role.role_name.snakecase) ||
118
+ reading.text.gsub(/ *\{0\} */,'').gsub(/[- ]/,'_')
119
+ ).split(/_/)
120
+ )
117
121
  end
118
122
 
119
123
  # debug "\tleading_adjective=#{(p=preferred_role_ref).leading_adjective}, role_name=#{role.role_name}, role player=#{role.object_type.name}, trailing_adjective=#{p.trailing_adjective}"
@@ -131,7 +135,7 @@ module ActiveFacts
131
135
  role_words << ta.gsub(/[- ]/,'_') if ta && ta != "" and !role_name
132
136
  n = role_words.map{|w| w.gsub(/([a-z])([A-Z]+)/,'\1_\2').downcase}*"_"
133
137
  # debug "\tresult=#{n}"
134
- n.gsub(' ','_')
138
+ return b.call(n.gsub(' ','_').split(/_/))
135
139
  end
136
140
 
137
141
  def skip_fact_type(f)