activefacts 1.6.0 → 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (169) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +14 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +4 -0
  5. data/Gemfile +14 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +60 -0
  8. data/Rakefile +3 -80
  9. data/activefacts.gemspec +36 -0
  10. data/bin/afgen +4 -2
  11. data/bin/cql +5 -1
  12. data/lib/activefacts.rb +3 -12
  13. data/lib/activefacts/{vocabulary/query_evaluator.rb → query/evaluator.rb} +0 -0
  14. data/lib/activefacts/version.rb +2 -2
  15. metadata +48 -296
  16. data/History.txt +0 -4
  17. data/LICENSE +0 -19
  18. data/Manifest.txt +0 -165
  19. data/README.rdoc +0 -81
  20. data/css/offline.css +0 -3
  21. data/css/orm2.css +0 -124
  22. data/css/print.css +0 -8
  23. data/css/style-print.css +0 -357
  24. data/css/style.css +0 -387
  25. data/download.html +0 -110
  26. data/examples/CQL/Address.cql +0 -44
  27. data/examples/CQL/Blog.cql +0 -54
  28. data/examples/CQL/CompanyDirectorEmployee.cql +0 -56
  29. data/examples/CQL/Death.cql +0 -17
  30. data/examples/CQL/Diplomacy.cql +0 -48
  31. data/examples/CQL/Genealogy.cql +0 -98
  32. data/examples/CQL/Insurance.cql +0 -320
  33. data/examples/CQL/Marriage.cql +0 -18
  34. data/examples/CQL/Metamodel.cql +0 -493
  35. data/examples/CQL/Monogamy.cql +0 -24
  36. data/examples/CQL/MultiInheritance.cql +0 -22
  37. data/examples/CQL/NonRoleId.cql +0 -14
  38. data/examples/CQL/OddIdentifier.cql +0 -18
  39. data/examples/CQL/OilSupply.cql +0 -53
  40. data/examples/CQL/OneToOnes.cql +0 -17
  41. data/examples/CQL/Orienteering.cql +0 -111
  42. data/examples/CQL/PersonPlaysGame.cql +0 -18
  43. data/examples/CQL/RedundantDependency.cql +0 -34
  44. data/examples/CQL/SchoolActivities.cql +0 -33
  45. data/examples/CQL/SeparateSubtype.cql +0 -30
  46. data/examples/CQL/ServiceDirector.cql +0 -276
  47. data/examples/CQL/SimplestUnary.cql +0 -12
  48. data/examples/CQL/Supervision.cql +0 -34
  49. data/examples/CQL/WaiterTips.cql +0 -33
  50. data/examples/CQL/Warehousing.cql +0 -101
  51. data/examples/CQL/WindowInRoomInBldg.cql +0 -28
  52. data/examples/CQL/unit.cql +0 -474
  53. data/examples/index.html +0 -420
  54. data/examples/intro.html +0 -327
  55. data/examples/local.css +0 -24
  56. data/index.html +0 -111
  57. data/lib/activefacts/cql.rb +0 -35
  58. data/lib/activefacts/cql/CQLParser.treetop +0 -158
  59. data/lib/activefacts/cql/Context.treetop +0 -48
  60. data/lib/activefacts/cql/Expressions.treetop +0 -67
  61. data/lib/activefacts/cql/FactTypes.treetop +0 -358
  62. data/lib/activefacts/cql/Language/English.treetop +0 -315
  63. data/lib/activefacts/cql/LexicalRules.treetop +0 -253
  64. data/lib/activefacts/cql/ObjectTypes.treetop +0 -210
  65. data/lib/activefacts/cql/Rakefile +0 -14
  66. data/lib/activefacts/cql/Terms.treetop +0 -183
  67. data/lib/activefacts/cql/ValueTypes.treetop +0 -202
  68. data/lib/activefacts/cql/compiler.rb +0 -156
  69. data/lib/activefacts/cql/compiler/clause.rb +0 -1137
  70. data/lib/activefacts/cql/compiler/constraint.rb +0 -581
  71. data/lib/activefacts/cql/compiler/entity_type.rb +0 -457
  72. data/lib/activefacts/cql/compiler/expression.rb +0 -443
  73. data/lib/activefacts/cql/compiler/fact.rb +0 -390
  74. data/lib/activefacts/cql/compiler/fact_type.rb +0 -421
  75. data/lib/activefacts/cql/compiler/query.rb +0 -106
  76. data/lib/activefacts/cql/compiler/shared.rb +0 -161
  77. data/lib/activefacts/cql/compiler/value_type.rb +0 -174
  78. data/lib/activefacts/cql/nodes.rb +0 -49
  79. data/lib/activefacts/cql/parser.rb +0 -241
  80. data/lib/activefacts/dependency_analyser.rb +0 -182
  81. data/lib/activefacts/generate/absorption.rb +0 -70
  82. data/lib/activefacts/generate/composition.rb +0 -118
  83. data/lib/activefacts/generate/cql.rb +0 -714
  84. data/lib/activefacts/generate/dm.rb +0 -279
  85. data/lib/activefacts/generate/help.rb +0 -64
  86. data/lib/activefacts/generate/helpers/inject.rb +0 -16
  87. data/lib/activefacts/generate/helpers/oo.rb +0 -162
  88. data/lib/activefacts/generate/helpers/ordered.rb +0 -605
  89. data/lib/activefacts/generate/helpers/rails.rb +0 -57
  90. data/lib/activefacts/generate/html/glossary.rb +0 -461
  91. data/lib/activefacts/generate/json.rb +0 -337
  92. data/lib/activefacts/generate/null.rb +0 -32
  93. data/lib/activefacts/generate/rails/models.rb +0 -246
  94. data/lib/activefacts/generate/rails/schema.rb +0 -216
  95. data/lib/activefacts/generate/records.rb +0 -46
  96. data/lib/activefacts/generate/ruby.rb +0 -133
  97. data/lib/activefacts/generate/sql/mysql.rb +0 -280
  98. data/lib/activefacts/generate/sql/server.rb +0 -273
  99. data/lib/activefacts/generate/stats.rb +0 -69
  100. data/lib/activefacts/generate/text.rb +0 -27
  101. data/lib/activefacts/generate/topics.rb +0 -265
  102. data/lib/activefacts/generate/traits/datavault.rb +0 -241
  103. data/lib/activefacts/generate/traits/oo.rb +0 -73
  104. data/lib/activefacts/generate/traits/ordered.rb +0 -33
  105. data/lib/activefacts/generate/traits/ruby.rb +0 -210
  106. data/lib/activefacts/generate/transform/datavault.rb +0 -266
  107. data/lib/activefacts/generate/transform/surrogate.rb +0 -214
  108. data/lib/activefacts/generate/version.rb +0 -26
  109. data/lib/activefacts/input/cql.rb +0 -43
  110. data/lib/activefacts/input/orm.rb +0 -1636
  111. data/lib/activefacts/mapping/rails.rb +0 -132
  112. data/lib/activefacts/persistence.rb +0 -15
  113. data/lib/activefacts/persistence/columns.rb +0 -446
  114. data/lib/activefacts/persistence/foreignkey.rb +0 -187
  115. data/lib/activefacts/persistence/index.rb +0 -240
  116. data/lib/activefacts/persistence/object_type.rb +0 -198
  117. data/lib/activefacts/persistence/reference.rb +0 -434
  118. data/lib/activefacts/persistence/tables.rb +0 -380
  119. data/lib/activefacts/registry.rb +0 -11
  120. data/lib/activefacts/support.rb +0 -132
  121. data/lib/activefacts/vocabulary.rb +0 -9
  122. data/lib/activefacts/vocabulary/extensions.rb +0 -1348
  123. data/lib/activefacts/vocabulary/metamodel.rb +0 -570
  124. data/lib/activefacts/vocabulary/verbaliser.rb +0 -804
  125. data/script/txt2html +0 -71
  126. data/spec/absorption_spec.rb +0 -95
  127. data/spec/cql/comparison_spec.rb +0 -89
  128. data/spec/cql/context_spec.rb +0 -94
  129. data/spec/cql/contractions_spec.rb +0 -224
  130. data/spec/cql/deontic_spec.rb +0 -88
  131. data/spec/cql/entity_type_spec.rb +0 -320
  132. data/spec/cql/expressions_spec.rb +0 -66
  133. data/spec/cql/fact_type_matching_spec.rb +0 -338
  134. data/spec/cql/french_spec.rb +0 -21
  135. data/spec/cql/parser/bad_literals_spec.rb +0 -86
  136. data/spec/cql/parser/constraints_spec.rb +0 -19
  137. data/spec/cql/parser/entity_types_spec.rb +0 -106
  138. data/spec/cql/parser/expressions_spec.rb +0 -199
  139. data/spec/cql/parser/fact_types_spec.rb +0 -44
  140. data/spec/cql/parser/literals_spec.rb +0 -312
  141. data/spec/cql/parser/pragmas_spec.rb +0 -89
  142. data/spec/cql/parser/value_types_spec.rb +0 -42
  143. data/spec/cql/role_matching_spec.rb +0 -148
  144. data/spec/cql/samples_spec.rb +0 -244
  145. data/spec/cql_cql_spec.rb +0 -73
  146. data/spec/cql_dm_spec.rb +0 -136
  147. data/spec/cql_mysql_spec.rb +0 -69
  148. data/spec/cql_parse_spec.rb +0 -34
  149. data/spec/cql_ruby_spec.rb +0 -73
  150. data/spec/cql_sql_spec.rb +0 -72
  151. data/spec/cql_symbol_tables_spec.rb +0 -261
  152. data/spec/cqldump_spec.rb +0 -170
  153. data/spec/helpers/array_matcher.rb +0 -23
  154. data/spec/helpers/ctrl_c_support.rb +0 -52
  155. data/spec/helpers/diff_matcher.rb +0 -39
  156. data/spec/helpers/file_matcher.rb +0 -34
  157. data/spec/helpers/parse_to_ast_matcher.rb +0 -80
  158. data/spec/helpers/string_matcher.rb +0 -30
  159. data/spec/helpers/test_parser.rb +0 -15
  160. data/spec/norma_cql_spec.rb +0 -66
  161. data/spec/norma_ruby_spec.rb +0 -62
  162. data/spec/norma_ruby_sql_spec.rb +0 -107
  163. data/spec/norma_sql_spec.rb +0 -57
  164. data/spec/norma_tables_spec.rb +0 -95
  165. data/spec/ruby_api_spec.rb +0 -23
  166. data/spec/spec_helper.rb +0 -35
  167. data/spec/transform_surrogate_spec.rb +0 -59
  168. data/status.html +0 -138
  169. data/why.html +0 -60
@@ -1,605 +0,0 @@
1
- #
2
- # ActiveFacts Generators.
3
- # Generation support superclass that sequences entity types to avoid forward references.
4
- #
5
- # Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
6
- #
7
- require 'activefacts/api'
8
- require 'activefacts/generate/helpers/inject'
9
- require 'activefacts/generate/traits/ordered'
10
-
11
- module ActiveFacts
12
- module Generate #:nodoc:
13
- module Helpers #:nodoc:
14
- class OrderedDumper #:nodoc:
15
- # Base class for generators of object-oriented class libraries for an ActiveFacts vocabulary.
16
- def initialize(vocabulary, *options)
17
- @vocabulary = vocabulary
18
- @vocabulary = @vocabulary.Vocabulary.values[0] if ActiveFacts::API::Constellation === @vocabulary
19
- options.each{|option| set_option(option) }
20
- end
21
-
22
- def set_option(option)
23
- end
24
-
25
- def puts(*a)
26
- @out.puts *a
27
- end
28
-
29
- def print(*a)
30
- @out.print *a
31
- end
32
-
33
- def generate(out = $>)
34
- @out = out
35
- vocabulary_start
36
- units_dump
37
- value_types_dump
38
- entity_types_dump
39
- fact_types_dump
40
- constraints_dump
41
- vocabulary_end
42
- end
43
-
44
- def units_dump
45
- done_banner = false
46
- units = @vocabulary.all_unit.to_a.sort_by{|u| u.name.gsub(/ /,'')}
47
- while units.size > 0
48
- i = 0
49
- while i < units.size
50
- unit = units[i]
51
- i += 1
52
-
53
- # Skip this one if the precursors haven't yet been dumped:
54
- next if unit.all_derivation_as_derived_unit.detect{|d| units.include?(d.base_unit) }
55
-
56
- # Even if we skip, we're done with this unit
57
- units.delete(unit)
58
- i -= 1
59
-
60
- # Skip value-type derived units
61
- next if unit.name =~ /\^/
62
-
63
- if !done_banner
64
- done_banner = true
65
- units_banner
66
- end
67
- unit_dump(unit)
68
- end
69
- end
70
- units_end if done_banner
71
- end
72
-
73
- def value_type_fork(o)
74
- if o.name == "_ImplicitBooleanValueType"
75
- # do nothing
76
- elsif
77
- !o.supertype # No supertype, i.e. a base type
78
- o.all_role.size == 0 && # No roles
79
- !o.is_independent && # not independent
80
- !o.value_constraint && # No value constraints
81
- o.concept.all_context_note_as_relevant_concept.size == 0 && # No context notes
82
- o.all_instance.size == 0 # No instances
83
- data_type_dump(o)
84
- else
85
- super_type_name = o.supertype ? o.supertype.name : o.name
86
- length = (l = o.length) && l > 0 ? "#{l}" : nil
87
- scale = (s = o.scale) && s > 0 ? "#{s}" : nil
88
- facets = { :length => length, :scale => scale }
89
- value_type_dump(o, super_type_name, facets)
90
- end
91
- end
92
-
93
- def value_types_dump
94
- done_banner = false
95
- @vocabulary.all_object_type.sort_by{|o| o.name.gsub(/ /,'')}.each{|o|
96
- next unless o.is_a?(ActiveFacts::Metamodel::ValueType)
97
-
98
- value_type_banner unless done_banner
99
- done_banner = true
100
-
101
- value_type_chain_dump(o)
102
- # @object_types_dumped[o] = true
103
- o.ordered_dumped!
104
- }
105
- value_type_end if done_banner
106
- end
107
-
108
- # Ensure that supertype gets dumped first
109
- def value_type_chain_dump(o)
110
- return if o.ordered_dumped
111
- value_type_chain_dump(o.supertype) if (o.supertype && !o.supertype.ordered_dumped)
112
- value_type_fork(o)
113
- o.ordered_dumped!
114
- end
115
-
116
- # Try to dump entity types in order of name, but we need
117
- # to dump ETs before they're referenced in preferred ids
118
- # if possible (it's not always, there may be loops!)
119
- def entity_types_dump
120
- # Build hash tables of precursors and followers to use:
121
- @precursors, @followers = *build_entity_dependencies
122
-
123
- done_banner = false
124
- sorted = @vocabulary.all_object_type.select{|o|
125
- o.is_a?(ActiveFacts::Metamodel::EntityType) # and !o.fact_type
126
- }.sort_by{|o| o.name.gsub(/ /,'')}
127
- panic = nil
128
- while true do
129
- count_this_pass = 0
130
- skipped_this_pass = 0
131
- sorted.each{|o|
132
- next if o.ordered_dumped # Already done
133
-
134
- trace :ordered, "Panicing to dump #{panic.name}" if panic
135
- # Can we do this yet?
136
- remaining_precursors = Array(@precursors[o])-[o]
137
- if (o != panic and # We don't *have* to do it (panic mode)
138
- remaining_precursors.size > 0) # precursors - still blocked
139
- trace :ordered, "Can't dump #{o.name} despite panic for #{panic.name}, it still needs #{remaining_precursors.map(&:name)*', '}" if panic
140
- skipped_this_pass += 1
141
- next
142
- end
143
- trace :ordered, "Dumping #{o.name} in panic mode, even though it still needs #{remaining_precursors.map(&:name)*', '}" if panic
144
-
145
- entity_type_banner unless done_banner
146
- done_banner = true
147
-
148
- # We're going to emit o - remove it from precursors of others:
149
- (@followers[o]||[]).each{|f|
150
- @precursors[f] -= [o]
151
- }
152
- count_this_pass += 1
153
- panic = nil
154
-
155
- if (o.fact_type)
156
- fact_type_dump_with_dependents(o.fact_type)
157
- released_fact_types_dump(o)
158
- else
159
- entity_type_dump(o)
160
- released_fact_types_dump(o)
161
- end
162
-
163
- entity_type_group_end
164
- }
165
-
166
- # Check that we made progress if there's any to make:
167
- if count_this_pass == 0 && skipped_this_pass > 0
168
- =begin
169
- if panic # We were already panicing... what to do now?
170
- # This won't happen again unless the above code is changed to decide it can't dump "panic".
171
- bad = sorted.select do |o|
172
- o.is_a?(ActiveFacts::Metamodel::EntityType) &&
173
- !o.ordered_dumped &&
174
- (Array(@precursors[o])-[o]).size > 0 &&
175
- (Array(@followers[o])-[o]).size > 0
176
- end
177
-
178
- raise "Unresolvable cycle of forward references: " +
179
- bad.map { |o| o.name }*', ' +
180
- ":\n\t" +
181
- (
182
- bad.map do |o|
183
- o.name +
184
- " depends on " +
185
- (@precursors[o].uniq.map{|p| p.name}.sort*', ')
186
- end
187
- ) * "\n\t" +
188
- "\n"
189
- =end
190
- # else
191
- # Find the object that has the most followers and no fwd-ref'd supertypes:
192
- # This selection might be better if we allow PI roles to be fwd-ref'd...
193
- panic = sorted.
194
- select{|o| !o.ordered_dumped }.
195
- sort_by{|o|
196
- f = (@followers[o] || []) - [o];
197
- o.supertypes.detect{|s| !s.ordered_dumped } ? 0 : -f.size
198
- }[0]
199
- trace :ordered, "Panic mode, selected #{panic.name} next"
200
- # end
201
- end
202
-
203
- break if skipped_this_pass == 0 # All done.
204
-
205
- end
206
- end
207
-
208
- def identified_by(o, pi)
209
- # Different adjectives might be used for different readings.
210
- # Here, we must find the role_ref containing the adjectives that we need for each identifier,
211
- # which will be attached to the uniqueness constraint on this object in the binary FT that
212
- # attaches that identifying role.
213
- identifying_role_refs = pi.role_sequence.all_role_ref.sort_by{|role_ref| role_ref.ordinal}
214
-
215
- # We need to get the adjectives for the roles from the identifying fact's preferred readings:
216
- identifying_facts = ([o.fact_type]+identifying_role_refs.map{|rr| rr.role.fact_type }).compact.uniq
217
-
218
- identification = identified_by_roles_and_facts(o, identifying_role_refs, identifying_facts)
219
-
220
- identification
221
- end
222
-
223
- def describe_fact_type(fact_type, highlight = nil)
224
- (fact_type.entity_type ? fact_type.entity_type.name : "")+
225
- describe_roles(fact_type.all_role, highlight)
226
- end
227
-
228
- def describe_roles(roles, highlight = nil)
229
- "("+
230
- roles.map{|role| role.object_type.name + (role == highlight ? "*" : "")}*", "+
231
- ")"
232
- end
233
-
234
- def describe_role_sequence(role_sequence)
235
- "("+
236
- role_sequence.all_role_ref.map{|role_ref| role_ref.role.object_type.name }*", "+
237
- ")"
238
- end
239
-
240
- # This returns an array of two hash tables each keyed by an EntityType.
241
- # The values of each hash entry are the precursors and followers (respectively) of that entity.
242
- def build_entity_dependencies
243
- @vocabulary.all_object_type.inject([{},{}]) { |a, o|
244
- if o.is_a?(ActiveFacts::Metamodel::EntityType)
245
- precursor = a[0]
246
- follower = a[1]
247
- blocked = false
248
- pi = o.preferred_identifier
249
- if pi
250
- pi.role_sequence.all_role_ref.each{|rr|
251
- role = rr.role
252
- player = role.object_type
253
- # REVISIT: If we decide to emit value types on demand, need to remove this:
254
- next unless player.is_a?(ActiveFacts::Metamodel::EntityType)
255
- # player is a precursor of o
256
- (precursor[o] ||= []) << player if (player != o)
257
- (follower[player] ||= []) << o if (player != o)
258
- }
259
- end
260
- if o.fact_type
261
- o.fact_type.all_role.each do |role|
262
- next unless role.object_type.is_a?(ActiveFacts::Metamodel::EntityType)
263
- (precursor[o] ||= []) << role.object_type
264
- (follower[role.object_type] ||= []) << o
265
- end
266
- end
267
-
268
- # Supertypes are precursors too:
269
- subtyping = o.all_type_inheritance_as_supertype
270
- next a if subtyping.size == 0
271
- subtyping.each{|ti|
272
- # debug ti.class.roles.verbalise; trace "all_type_inheritance_as_supertype"; exit
273
- s = ti.subtype
274
- (precursor[s] ||= []) << o
275
- (follower[o] ||= []) << s
276
- }
277
- # REVISIT: Need to use this to order ValueTypes after their supertypes
278
- # else
279
- # o.all_value_type_as_supertype.each { |s|
280
- # (precursor[s] ||= []) << o
281
- # (follower[o] ||= []) << s
282
- # }
283
- end
284
- a
285
- }
286
- end
287
-
288
- # Dump all fact types for which all precursors (of which "o" is one) have been emitted:
289
- def released_fact_types_dump(o)
290
- roles = o.all_role
291
- begin
292
- progress = false
293
- roles.map(&:fact_type).uniq.select{|fact_type|
294
- # The fact type hasn't already been dumped but all its role players have
295
- !fact_type.ordered_dumped &&
296
- !fact_type.is_a?(ActiveFacts::Metamodel::LinkFactType) &&
297
- !fact_type.all_role.detect{|r| !r.object_type.ordered_dumped } &&
298
- !fact_type.entity_type &&
299
- derivation_precursors_complete(fact_type)
300
- # REVISIT: A derived fact type must not be dumped before its dependent fact types have
301
- }.sort_by{|fact_type|
302
- fact_type_key(fact_type)
303
- }.each{|fact_type|
304
- fact_type_dump_with_dependents(fact_type)
305
- # Objectified Fact Types may release additional fact types
306
- roles += fact_type.entity_type.all_role.sort_by{|role| role.ordinal} if fact_type.entity_type
307
- progress = true
308
- }
309
- end while progress
310
- end
311
-
312
- def derivation_precursors_complete(fact_type)
313
- pr = fact_type.preferred_reading
314
- return true unless jr = pr.role_sequence.all_role_ref.to_a[0].play
315
- query = jr.variable.query
316
- return false if query.all_step.detect{|js| !js.fact_type.ordered_dumped }
317
- return false if query.all_variable.detect{|jn| !jn.object_type.ordered_dumped }
318
- true
319
- end
320
-
321
- def skip_fact_type(f)
322
- return true if f.is_a?(ActiveFacts::Metamodel::TypeInheritance)
323
- return false if f.entity_type && !f.entity_type.ordered_dumped
324
-
325
- # REVISIT: There might be constraints we have to merge into the nested entity or subtype.
326
- # These will come up as un-handled constraints:
327
- # Dump this fact type only if it contains a presence constraint we've missed:
328
- pcs = @presence_constraints_by_fact[f]
329
- pcs && pcs.size > 0 && !pcs.detect{|c| !c.ordered_dumped }
330
- end
331
-
332
- # Dump one fact type.
333
- # Include as many as possible internal constraints in the fact type readings.
334
- def fact_type_dump_with_dependents(fact_type)
335
- fact_type.ordered_dumped!
336
- return if skip_fact_type(fact_type)
337
-
338
- if (et = fact_type.entity_type) &&
339
- (pi = et.preferred_identifier) &&
340
- pi.role_sequence.all_role_ref.detect{|rr| rr.role.fact_type != fact_type }
341
- # trace "Dumping objectified FT #{et.name} as an entity, non-fact PI"
342
- entity_type_dump(et)
343
- released_fact_types_dump(et)
344
- return
345
- end
346
-
347
- # trace "#{fact_type.name} has readings:\n\t#{fact_type.readings.map(&:name)*"\n\t"}"
348
- # trace "Dumping #{fact_type.concept.guid} as a fact type"
349
-
350
- # Fact types that aren't nested have no names
351
- name = fact_type.entity_type && fact_type.entity_type.name
352
-
353
- fact_type_dump(fact_type, name)
354
-
355
- # REVISIT: Go through the residual constraints and re-process appropriate readings to show them
356
-
357
- #CJH: Necessary?
358
- fact_type.ordered_dumped!
359
- fact_type.entity_type.ordered_dumped! if fact_type.entity_type
360
- end
361
-
362
- # Dump fact types.
363
- def fact_types_dump
364
- # REVISIT: Uniqueness on the LHS of a binary can be coded using "distinct"
365
-
366
- # The only fact types that can be remaining are those involving only value types,
367
- # since we dumped every fact type as soon as all relevant entities were dumped.
368
- # Iterate over all fact types of all value types, looking for these strays.
369
-
370
- done_banner = false
371
- fact_collection = @vocabulary.constellation.FactType
372
- fact_collection.keys.select{|fact_id|
373
- fact_type = fact_collection[fact_id] and
374
- !fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance) and
375
- !fact_type.is_a?(ActiveFacts::Metamodel::LinkFactType) and
376
- !fact_type.ordered_dumped and
377
- !skip_fact_type(fact_type) and
378
- !fact_type.all_role.detect{|r| r.object_type.is_a?(ActiveFacts::Metamodel::EntityType) }
379
- }.sort_by{|fact_id|
380
- fact_type = fact_collection[fact_id]
381
- fact_type_key(fact_type)
382
- }.each{|fact_id|
383
- fact_type = fact_collection[fact_id]
384
-
385
- fact_type_banner unless done_banner
386
- done_banner = true
387
- fact_type_dump_with_dependents(fact_type)
388
- }
389
-
390
- # REVISIT: Find out why some fact types are missed during entity dumping:
391
- @vocabulary.constellation.FactType.values.select{|fact_type|
392
- !fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance) &&
393
- !fact_type.is_a?(ActiveFacts::Metamodel::LinkFactType)
394
- }.sort_by{|fact_type|
395
- fact_type_key(fact_type)
396
- }.each{|fact_type|
397
- next if fact_type.ordered_dumped
398
- # trace "Not dumped #{fact_type.verbalise}(#{fact_type.all_role.map{|r| r.object_type.name}*", "})"
399
- fact_type_banner unless done_banner
400
- done_banner = true
401
- fact_type_dump_with_dependents(fact_type)
402
- }
403
-
404
- fact_type_end if done_banner
405
- end
406
-
407
- def fact_instances_dump
408
- @vocabulary.fact_types.each{|f|
409
- # Dump the instances:
410
- f.facts.each{|i|
411
- raise "REVISIT: Not dumping fact instances"
412
- trace "\t\t"+i.to_s
413
- }
414
- }
415
- end
416
-
417
- # Arrange for objectified fact types to appear in order of name, after other fact types.
418
- # Facts are ordered alphabetically by the names of their role players,
419
- # then by preferred_reading (subtyping fact types have no preferred_reading).
420
- def fact_type_key(fact_type)
421
- role_names =
422
- if (pr = fact_type.preferred_reading)
423
- pr.role_sequence.
424
- all_role_ref.
425
- sort_by{|role_ref| role_ref.ordinal}.
426
- map{|role_ref| [ role_ref.leading_adjective, role_ref.role.object_type.name, role_ref.trailing_adjective ].compact*"-" } +
427
- [pr.text]
428
- else
429
- fact_type.all_role.map{|role| role.object_type.name }
430
- end
431
-
432
- (fact_type.entity_type ? [fact_type.entity_type.name] : [""]) + role_names
433
- end
434
-
435
- def role_ref_key(role_ref)
436
- [ role_ref.leading_adjective, role_ref.role.object_type.name, role_ref.trailing_adjective ].compact*"-" +
437
- " in " +
438
- role_ref.role.fact_type.preferred_reading.expand
439
- end
440
-
441
- def constraint_sort_key(c)
442
- case c
443
- when ActiveFacts::Metamodel::RingConstraint
444
- [ 1,
445
- c.ring_type,
446
- c.role.object_type.name,
447
- c.other_role.object_type.name,
448
- c.name||""
449
- ]
450
- when ActiveFacts::Metamodel::SetExclusionConstraint
451
- [ 2+(c.is_mandatory ? 0 : 1),
452
- c.all_set_comparison_roles.map{|scrs|
453
- scrs.role_sequence.all_role_ref.map{|rr|
454
- role_ref_key(rr)
455
- }
456
- },
457
- c.name||""
458
- ]
459
- when ActiveFacts::Metamodel::SetEqualityConstraint
460
- [ 4,
461
- c.all_set_comparison_roles.map{|scrs|
462
- scrs.role_sequence.all_role_ref.map{|rr|
463
- role_ref_key(rr)
464
- }
465
- },
466
- c.name||""
467
- ]
468
- when ActiveFacts::Metamodel::SubsetConstraint
469
- [ 5,
470
- [c.superset_role_sequence, c.subset_role_sequence].map{|rs|
471
- rs.all_role_ref.map{|rr|
472
- role_ref_key(rr)
473
- }
474
- },
475
- c.name||""
476
- ]
477
- when ActiveFacts::Metamodel::PresenceConstraint
478
- [ 6,
479
- c.role_sequence.all_role_ref.map{|rr|
480
- role_ref_key(rr)
481
- },
482
- c.name||""
483
- ]
484
- end
485
- end
486
-
487
- def constraints_dump
488
- heading = false
489
- @vocabulary.
490
- all_constraint.
491
- reject{|c| c.ordered_dumped}.
492
- sort_by{ |c| constraint_sort_key(c) }.
493
- each do |c|
494
- # Skip some PresenceConstraints:
495
- if c.is_a?(ActiveFacts::Metamodel::PresenceConstraint)
496
- # Skip uniqueness constraints that cover all roles of a fact type, they're implicit
497
- fact_types = c.role_sequence.all_role_ref.map{|rr| rr.role.fact_type}.uniq
498
- if fact_types.size == 1 &&
499
- !c.role_sequence.all_role_ref.detect{|rr| rr.play } &&
500
- c.max_frequency == 1 && # Uniqueness
501
- fact_types[0].all_role.size == c.role_sequence.all_role_ref.size
502
- next
503
- end
504
-
505
- # Skip internal PresenceConstraints over TypeInheritances:
506
- next if c.role_sequence.all_role_ref.size == 1 &&
507
- fact_types[0].is_a?(ActiveFacts::Metamodel::TypeInheritance)
508
- end
509
-
510
- constraint_banner unless heading
511
- heading = true
512
-
513
- # Skip presence constraints on value types:
514
- # next if ActiveFacts::PresenceConstraint === c &&
515
- # ActiveFacts::ValueType === c.object_type
516
- constraint_dump(c)
517
- end
518
- constraint_end if heading
519
- end
520
-
521
- def vocabulary_start
522
- trace "Should override vocabulary_start"
523
- end
524
-
525
- def vocabulary_end
526
- trace "Should override vocabulary_end"
527
- end
528
-
529
- def units_banner
530
- end
531
-
532
- def units_end
533
- end
534
-
535
- def unit_dump unit
536
- end
537
-
538
- def value_type_banner
539
- trace "Should override value_type_banner"
540
- end
541
-
542
- def value_type_end
543
- trace "Should override value_type_end"
544
- end
545
-
546
- def data_type_dump(o)
547
- trace "Should override data_type_dump"
548
- end
549
-
550
- def value_type_dump(o, super_type_name, facets)
551
- trace "Should override value_type_dump"
552
- end
553
-
554
- def entity_type_banner
555
- trace "Should override entity_type_banner"
556
- end
557
-
558
- def entity_type_group_end
559
- trace "Should override entity_type_group_end"
560
- end
561
-
562
- def non_subtype_dump(o, pi)
563
- trace "Should override non_subtype_dump"
564
- end
565
-
566
- def subtype_dump(o, supertypes, pi = nil)
567
- trace "Should override subtype_dump"
568
- end
569
-
570
- def append_ring_to_reading(reading, ring)
571
- trace "Should override append_ring_to_reading"
572
- end
573
-
574
- def fact_type_banner
575
- trace "Should override fact_type_banner"
576
- end
577
-
578
- def fact_type_end
579
- trace "Should override fact_type_end"
580
- end
581
-
582
- def fact_type_dump(fact_type, name)
583
- trace "Should override fact_type_dump"
584
- end
585
-
586
- def constraint_banner
587
- trace "Should override constraint_banner"
588
- end
589
-
590
- def constraint_end
591
- trace "Should override constraint_end"
592
- end
593
-
594
- def constraint_dump(c)
595
- trace "Should override constraint_dump"
596
- end
597
-
598
- end
599
-
600
- def dump(vocabulary, out = $>)
601
- OrderedDumper.new(vocabulary).dump(out)
602
- end
603
- end
604
- end
605
- end