activefacts 0.6.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 (84) hide show
  1. data/History.txt +4 -0
  2. data/Manifest.txt +83 -0
  3. data/README.rdoc +81 -0
  4. data/Rakefile +41 -0
  5. data/bin/afgen +46 -0
  6. data/bin/cql +52 -0
  7. data/examples/CQL/Address.cql +46 -0
  8. data/examples/CQL/Blog.cql +54 -0
  9. data/examples/CQL/CompanyDirectorEmployee.cql +51 -0
  10. data/examples/CQL/Death.cql +16 -0
  11. data/examples/CQL/Genealogy.cql +95 -0
  12. data/examples/CQL/Marriage.cql +18 -0
  13. data/examples/CQL/Metamodel.cql +238 -0
  14. data/examples/CQL/MultiInheritance.cql +19 -0
  15. data/examples/CQL/OilSupply.cql +47 -0
  16. data/examples/CQL/Orienteering.cql +108 -0
  17. data/examples/CQL/PersonPlaysGame.cql +17 -0
  18. data/examples/CQL/SchoolActivities.cql +31 -0
  19. data/examples/CQL/SimplestUnary.cql +12 -0
  20. data/examples/CQL/SubtypePI.cql +32 -0
  21. data/examples/CQL/Warehousing.cql +99 -0
  22. data/examples/CQL/WindowInRoomInBldg.cql +22 -0
  23. data/lib/activefacts.rb +10 -0
  24. data/lib/activefacts/api.rb +25 -0
  25. data/lib/activefacts/api/concept.rb +384 -0
  26. data/lib/activefacts/api/constellation.rb +106 -0
  27. data/lib/activefacts/api/entity.rb +239 -0
  28. data/lib/activefacts/api/instance.rb +54 -0
  29. data/lib/activefacts/api/numeric.rb +158 -0
  30. data/lib/activefacts/api/role.rb +94 -0
  31. data/lib/activefacts/api/standard_types.rb +67 -0
  32. data/lib/activefacts/api/support.rb +59 -0
  33. data/lib/activefacts/api/value.rb +122 -0
  34. data/lib/activefacts/api/vocabulary.rb +120 -0
  35. data/lib/activefacts/cql.rb +31 -0
  36. data/lib/activefacts/cql/CQLParser.treetop +104 -0
  37. data/lib/activefacts/cql/Concepts.treetop +112 -0
  38. data/lib/activefacts/cql/DataTypes.treetop +66 -0
  39. data/lib/activefacts/cql/Expressions.treetop +113 -0
  40. data/lib/activefacts/cql/FactTypes.treetop +185 -0
  41. data/lib/activefacts/cql/Language/English.treetop +92 -0
  42. data/lib/activefacts/cql/LexicalRules.treetop +169 -0
  43. data/lib/activefacts/cql/Rakefile +6 -0
  44. data/lib/activefacts/cql/parser.rb +88 -0
  45. data/lib/activefacts/generate/absorption.rb +87 -0
  46. data/lib/activefacts/generate/cql.rb +441 -0
  47. data/lib/activefacts/generate/cql/html.rb +397 -0
  48. data/lib/activefacts/generate/null.rb +19 -0
  49. data/lib/activefacts/generate/ordered.rb +557 -0
  50. data/lib/activefacts/generate/ruby.rb +326 -0
  51. data/lib/activefacts/generate/sql/server.rb +164 -0
  52. data/lib/activefacts/generate/text.rb +21 -0
  53. data/lib/activefacts/input/cql.rb +1268 -0
  54. data/lib/activefacts/input/orm.rb +926 -0
  55. data/lib/activefacts/persistence.rb +1 -0
  56. data/lib/activefacts/persistence/composition.rb +653 -0
  57. data/lib/activefacts/support.rb +51 -0
  58. data/lib/activefacts/version.rb +3 -0
  59. data/lib/activefacts/vocabulary.rb +6 -0
  60. data/lib/activefacts/vocabulary/extensions.rb +343 -0
  61. data/lib/activefacts/vocabulary/metamodel.rb +303 -0
  62. data/script/txt2html +71 -0
  63. data/spec/absorption_spec.rb +95 -0
  64. data/spec/api/autocounter.rb +82 -0
  65. data/spec/api/constellation.rb +130 -0
  66. data/spec/api/entity_type.rb +101 -0
  67. data/spec/api/instance.rb +428 -0
  68. data/spec/api/roles.rb +122 -0
  69. data/spec/api/value_type.rb +112 -0
  70. data/spec/api_spec.rb +14 -0
  71. data/spec/cql_cql_spec.rb +58 -0
  72. data/spec/cql_parse_spec.rb +31 -0
  73. data/spec/cql_ruby_spec.rb +60 -0
  74. data/spec/cql_sql_spec.rb +54 -0
  75. data/spec/cql_symbol_tables_spec.rb +259 -0
  76. data/spec/cql_unit_spec.rb +336 -0
  77. data/spec/cqldump_spec.rb +169 -0
  78. data/spec/norma_cql_spec.rb +48 -0
  79. data/spec/norma_ruby_spec.rb +50 -0
  80. data/spec/norma_sql_spec.rb +45 -0
  81. data/spec/norma_tables_spec.rb +94 -0
  82. data/spec/spec.opts +1 -0
  83. data/spec/spec_helper.rb +10 -0
  84. metadata +173 -0
@@ -0,0 +1,51 @@
1
+ #module ActiveFacts
2
+ $debug_indent = nil
3
+ $debug_nested = false
4
+ $debug_keys = nil
5
+ def debug(*args, &block)
6
+ unless $debug_indent
7
+ # First time, initialise the tracing environment
8
+ $debug_indent = 0
9
+ $debug_keys = {}
10
+ if (e = ENV["DEBUG"])
11
+ e.split(/[^a-z]/).each{|k| $debug_keys[k.to_sym] = true }
12
+ end
13
+ end
14
+
15
+ # Figure out whether this trace is enabled and nests:
16
+ control = (!args.empty? && Symbol === args[0]) ? args.shift : :all
17
+ key = control.to_s.sub(/_\Z/, '')
18
+ enabled = $debug_nested || $debug_keys[key.to_sym]
19
+ nesting = control.to_s =~ /_\Z/
20
+ old_nested = $debug_nested
21
+ $debug_nested = nesting
22
+
23
+ # Emit the message if enabled or a parent is:
24
+ puts "# "+" "*$debug_indent + args.join(' ') if args.size > 0 && enabled
25
+
26
+ if block
27
+ begin
28
+ $debug_indent += 1 if enabled
29
+ r = yield # Return the value of the block
30
+ ensure
31
+ $debug_indent -= 1 if enabled
32
+ $debug_nesting = old_nested
33
+ end
34
+ else
35
+ r = enabled # Return whether enabled
36
+ end
37
+ r
38
+ end
39
+ #end
40
+
41
+ class Array
42
+ def duplicates(&b)
43
+ inject({}) do |h,e|
44
+ h[e] ||= 0
45
+ h[e] += 1
46
+ h
47
+ end.reject do |k,v|
48
+ v == 1
49
+ end.keys
50
+ end
51
+ end
@@ -0,0 +1,3 @@
1
+ module ActiveFacts
2
+ VERSION = '0.6.0'
3
+ end
@@ -0,0 +1,6 @@
1
+ #
2
+ # The ActiveFacts Vocabulary API, generated from Metamodel.orm with extensions:
3
+ # Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
4
+ #
5
+ require 'activefacts/vocabulary/metamodel'
6
+ require 'activefacts/vocabulary/extensions'
@@ -0,0 +1,343 @@
1
+ #
2
+ # Extensions to the ActiveFacts Vocabulary API (which is generated from the Metamodel)
3
+ # Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
4
+ #
5
+ module ActiveFacts
6
+ module Metamodel
7
+
8
+ class FactType
9
+ def all_reading_by_ordinal
10
+ all_reading.sort_by{|reading| reading.ordinal}
11
+ end
12
+
13
+ def preferred_reading
14
+ all_reading_by_ordinal[0]
15
+ end
16
+
17
+ def describe(highlight = nil)
18
+ (entity_type ? entity_type.name : "")+
19
+ '('+all_role.map{|role| role.describe(highlight) }*", "+')'
20
+ end
21
+
22
+ def default_reading(frequency_constraints = [], define_role_names = false)
23
+ preferred_reading.expand(frequency_constraints, define_role_names)
24
+ end
25
+ end
26
+
27
+ class Role
28
+ def describe(highlight = nil)
29
+ concept.name + (self == highlight ? "*" : "")
30
+ end
31
+
32
+ # Is there are internal uniqueness constraint on this role only?
33
+ def unique
34
+ all_role_ref.detect{|rr|
35
+ rs = rr.role_sequence
36
+ rs.all_role_ref.size == 1 and
37
+ rs.all_presence_constraint.detect{|pc|
38
+ pc.max_frequency == 1
39
+ }
40
+ }
41
+ end
42
+
43
+ # Return the RoleRef to this role from its fact type's preferred_reading
44
+ def preferred_reference
45
+ fact_type.preferred_reading.role_sequence.all_role_ref.detect{|rr| rr.role == self }
46
+ end
47
+ end
48
+
49
+ class JoinPath
50
+ def column_name(joiner = '-')
51
+ concept == input_role.concept ? input_role.preferred_reference.role_name(joiner) : Array(concept.name)
52
+ end
53
+
54
+ def describe
55
+ "#{input_role.fact_type.describe(input_role)}->" +
56
+ concept.name +
57
+ (output_role ? "->#{output_role.fact_type.describe(output_role)}":"")
58
+ end
59
+ end
60
+
61
+ class RoleRef
62
+ def describe
63
+ # The reference traverses the JoinPaths in sequence to the final role:
64
+ all_join_path.sort_by{|jp| jp.join_step}.map{ |jp| jp.describe + "." }*"" + role_name
65
+ end
66
+
67
+ def role_name(joiner = "-")
68
+ name_array =
69
+ if role.fact_type.all_role.size == 1
70
+ role.fact_type.preferred_reading.reading_text.gsub(/\{[0-9]\}/,'').strip.split(/\s/)
71
+ else
72
+ role.role_name || [leading_adjective, role.concept.name, trailing_adjective].compact.map{|w| w.split(/\s/)}.flatten
73
+ end
74
+ return joiner ? Array(name_array)*joiner : Array(name_array)
75
+ end
76
+ end
77
+
78
+ class RoleSequence
79
+ def describe
80
+ "("+
81
+ all_role_ref.sort_by{|rr| rr.ordinal}.map{|rr| rr.describe }*", "+
82
+ ")"
83
+ end
84
+ end
85
+
86
+ class ValueType
87
+ def supertypes_transitive
88
+ [self] + (supertype ? supertype.supertypes_transitive : [])
89
+ end
90
+
91
+ def subtypes
92
+ all_value_type_by_supertype
93
+ end
94
+ end
95
+
96
+ class EntityType
97
+ include ActiveFacts
98
+ def preferred_identifier
99
+ if fact_type
100
+
101
+ # For a nested fact type, the PI is a unique constraint over N or N-1 roles
102
+ fact_roles = fact_type.all_role
103
+ debug :pi, "Looking for PI on nested fact type #{name}" do
104
+ pi = catch :pi do
105
+ fact_roles[0,2].each{|r| # Try the first two roles of the fact type, that's enough
106
+ r.all_role_ref.map{|rr| # All role sequences that reference this role
107
+ role_sequence = rr.role_sequence
108
+
109
+ # The role sequence is only interesting if it cover only this fact's roles
110
+ next if role_sequence.all_role_ref.size < fact_roles.size-1 # Not enough roles
111
+ next if role_sequence.all_role_ref.size > fact_roles.size # Too many roles
112
+ next if role_sequence.all_role_ref.detect{|rsr| ft = rsr.role.fact_type; ft != fact_type }
113
+
114
+ # This role sequence is a candidate
115
+ pc = role_sequence.all_presence_constraint.detect{|c|
116
+ c.max_frequency == 1 && c.is_preferred_identifier
117
+ }
118
+ throw :pi, pc if pc
119
+ }
120
+ }
121
+ throw :pi, nil
122
+ end
123
+ debug :pi, "Got PI #{pi.name||pi.object_id} for nested #{name}" if pi
124
+ debug :pi, "Looking for PI on entity that nests this fact" unless pi
125
+ raise "Oops, pi for nested fact is #{pi.class}" unless !pi || PresenceConstraint === pi
126
+ return pi if pi
127
+ end
128
+ end
129
+
130
+ debug :pi, "Looking for PI for ordinary entity #{name} with #{all_role.size} roles:" do
131
+ debug :pi, "Roles are in fact types #{all_role.map{|r| r.fact_type.describe(r)}*", "}"
132
+ pi = catch :pi do
133
+ all_supertypes = supertypes_transitive
134
+ debug :pi, "PI roles must be played by one of #{all_supertypes.map(&:name)*", "}" if all_supertypes.size > 1
135
+ all_role.each{|role|
136
+ next unless role.unique || fact_type
137
+ ftroles = role.fact_type.all_role
138
+
139
+ # Skip roles in ternary and higher fact types, they're objectified, and in unaries, they can't identify us.
140
+ next if ftroles.size != 2
141
+
142
+ debug :pi, "Considering role in #{role.fact_type.describe(role)}"
143
+
144
+ # Find the related role which must be included in any PI:
145
+ # Note this works with unary fact types:
146
+ pi_role = ftroles[ftroles[0] != role ? 0 : -1]
147
+
148
+ next if ftroles.size == 2 && pi_role.concept == self
149
+ debug :pi, " Considering #{pi_role.concept.name} as a PI role"
150
+
151
+ # If this is an identifying role, the PI is a PC whose role_sequence spans the role.
152
+ # Walk through all role_sequences that span this role, and test each:
153
+ pi_role.all_role_ref.each{|rr|
154
+ role_sequence = rr.role_sequence # A role sequence that includes a possible role
155
+
156
+ debug :pi, " Considering role sequence #{role_sequence.describe}"
157
+
158
+ # All roles in this role_sequence must be in fact types which
159
+ # (apart from that role) only have roles played by the original
160
+ # entity type or a supertype.
161
+ #debug :pi, " All supertypes #{all_supertypes.map{|st| "#{st.object_id}=>#{st.name}"}*", "}"
162
+ if role_sequence.all_role_ref.detect{|rsr|
163
+ fact_type = rsr.role.fact_type
164
+ debug :pi, " Role Sequence touches #{fact_type.describe(pi_role)}"
165
+
166
+ fact_type_roles = fact_type.all_role
167
+ debug :pi, " residual is #{fact_type_roles.map{|r| r.concept.name}.inspect} minus #{rsr.role.concept.name}"
168
+ residual_roles = fact_type_roles-[rsr.role]
169
+ residual_roles.detect{|rfr|
170
+ debug :pi, " Checking residual role #{rfr.concept.object_id}=>#{rfr.concept.name}"
171
+ # This next line looks right, but breaks things. Find out what and why:
172
+ # !rfr.unique or
173
+ !all_supertypes.include?(rfr.concept)
174
+ }
175
+ }
176
+ debug :pi, " Discounting this role_sequence because it includes alien roles"
177
+ next
178
+ end
179
+
180
+ # Any presence constraint over this role sequence is a candidate
181
+ rr.role_sequence.all_presence_constraint.detect{|pc|
182
+ # Found it!
183
+ if pc.is_preferred_identifier
184
+ debug :pi, "found PI #{pc.name||pc.object_id}, is_preferred_identifier=#{pc.is_preferred_identifier.inspect} over #{pc.role_sequence.describe}"
185
+ throw :pi, pc
186
+ end
187
+ }
188
+ }
189
+ }
190
+ throw :pi, nil
191
+ end
192
+ raise "Oops, pi for entity is #{pi.class}" if pi && !(PresenceConstraint === pi)
193
+ debug :pi, "Got PI #{pi.name||pi.object_id} for #{name}" if pi
194
+
195
+ if !pi
196
+ if (supertype = identifying_supertype)
197
+ # This shouldn't happen now, as an identifying supertype is connected by a fact type
198
+ # that has a uniqueness constraint marked as the preferred identifier.
199
+ #debug :pi, "PI not found for #{name}, looking in supertype #{supertype.name}"
200
+ #pi = supertype.preferred_identifier
201
+ #return nil
202
+ elsif fact_type
203
+ fact_type.all_role.each{|role|
204
+ role.all_role_ref.each{|role_ref|
205
+ # Discount role sequences that contain roles not in this fact type:
206
+ next if role_ref.role_sequence.all_role_ref.detect{|rr| rr.role.fact_type != fact_type }
207
+ role_ref.role_sequence.all_presence_constraint.each{|pc|
208
+ next unless pc.is_preferred_identifier and pc.max_frequency == 1
209
+ pi = pc
210
+ break
211
+ }
212
+ break if pi
213
+ }
214
+ break if pi
215
+ }
216
+ else
217
+ debug :pi, "No PI found for #{name}"
218
+ end
219
+ end
220
+ raise "No PI found for #{name}" unless pi
221
+ pi
222
+ end
223
+ end
224
+
225
+ # An array of all direct subtypes:
226
+ def subtypes
227
+ # REVISIT: There's no sorting here. Should there be?
228
+ all_type_inheritance_by_supertype.map{|ti| ti.subtype }
229
+ end
230
+
231
+ def all_supertype_inheritance
232
+ all_type_inheritance_by_subtype.sort_by{|ti|
233
+ [ti.provides_identification ? 0 : 1, ti.supertype.name]
234
+ }
235
+ end
236
+
237
+ # An array all direct supertypes
238
+ def supertypes
239
+ all_supertype_inheritance.map{|ti|
240
+ ti.supertype
241
+ }
242
+ end
243
+
244
+ # An array of self followed by all supertypes in order:
245
+ def supertypes_transitive
246
+ ([self] + all_type_inheritance_by_subtype.map{|ti|
247
+ # debug ti.class.roles.verbalise; exit
248
+ ti.supertype.supertypes_transitive
249
+ }).flatten.uniq
250
+ end
251
+
252
+ # A subtype does not have a identifying_supertype if it defines its own identifier
253
+ def identifying_supertype
254
+ debug "Looking for identifying_supertype of #{name}"
255
+ all_type_inheritance_by_subtype.detect{|ti|
256
+ debug "considering supertype #{ti.supertype.name}"
257
+ next unless ti.provides_identification
258
+ debug "found identifying supertype of #{name}, it's #{ti.supertype.name}"
259
+ return ti.supertype
260
+ }
261
+ debug "Failed to find identifying supertype of #{name}"
262
+ return nil
263
+ end
264
+ end
265
+
266
+ class Reading
267
+ # The frequency_constraints array here, if supplied, may provide for each role either:
268
+ # * a PresenceConstraint to be verbalised against the relevant role, or
269
+ # * a String, used as a definite or indefinite article on the relevant role, or
270
+ # * an array containing two strings (an article and a super-type name)
271
+ # The order in the array is the same as the reading's role-sequence.
272
+ # REVISIT: This should probably be changed to be the fact role sequence.
273
+ #
274
+ # define_role_names here is false (use defined names), true (define names) or nil (neither)
275
+ def expand(frequency_constraints = [], define_role_names = false)
276
+ expanded = "#{reading_text}"
277
+ role_refs = role_sequence.all_role_ref.sort_by{|role_ref| role_ref.ordinal}
278
+ (0...role_refs.size).each{|i|
279
+ role_ref = role_refs[i]
280
+ role = role_ref.role
281
+ la = "#{role_ref.leading_adjective}"
282
+ la.sub!(/(.\b|.\Z)/, '\1-')
283
+ la = nil if la == ""
284
+ ta = "#{role_ref.trailing_adjective}"
285
+ ta.sub!(/(\b.|\A.)/, '-\1')
286
+ ta = nil if ta == ""
287
+
288
+ expanded.gsub!(/\{#{i}\}/) {
289
+ player = role_refs[i].role.concept
290
+ role_name = role.role_name
291
+ role_name = nil if role_name == ""
292
+ if role_name && define_role_names == false
293
+ la = ta = nil # When using role names, don't add adjectives
294
+ end
295
+ fc = frequency_constraints[i]
296
+ fc = fc.frequency if fc && PresenceConstraint === fc
297
+ if Array === fc
298
+ fc, player_name = *fc
299
+ else
300
+ player_name = player.name
301
+ end
302
+ [
303
+ fc ? fc : nil,
304
+ la,
305
+ define_role_names == false && role_name ? role_name : player_name,
306
+ ta,
307
+ define_role_names && role_name && player.name != role_name ? "(as #{role_name})" : nil
308
+ ].compact*" "
309
+ }
310
+ }
311
+ expanded.gsub!(/ *- */, '-') # Remove spaces around adjectives
312
+ #debug "Expanded '#{expanded}' using #{frequency_constraints.inspect}"
313
+ expanded
314
+ end
315
+
316
+ def words_and_role_refs
317
+ reading_text.
318
+ scan(/(?: |\{[0-9]+\}|[^{} ]+)/). # split up the text into words
319
+ reject{|s| s==' '}. # Remove white space
320
+ map do |frag| # and go through the bits
321
+ if frag =~ /\{([0-9]+)\}/
322
+ role_sequence.all_role_ref[$1.to_i]
323
+ else
324
+ frag
325
+ end
326
+ end
327
+ end
328
+ end
329
+
330
+ class PresenceConstraint
331
+ def frequency
332
+ min = min_frequency
333
+ max = max_frequency
334
+ [
335
+ ((min && min > 0 && min != max) ? "at least #{min == 1 ? "one" : min.to_s}" : nil),
336
+ ((max && min != max) ? "at most #{max == 1 ? "one" : max.to_s}" : nil),
337
+ ((max && min == max) ? "#{max == 1 ? "one" : max.to_s}" : nil)
338
+ ].compact * " and"
339
+ end
340
+ end
341
+
342
+ end
343
+ end
@@ -0,0 +1,303 @@
1
+ require 'activefacts/api'
2
+
3
+ module ActiveFacts
4
+ module Metamodel
5
+
6
+ class Adjective < String
7
+ value_type :length => 64
8
+ end
9
+
10
+ class ConstraintId < AutoCounter
11
+ value_type
12
+ end
13
+
14
+ class Denominator < UnsignedInteger
15
+ value_type :length => 32
16
+ end
17
+
18
+ class Enforcement < String
19
+ value_type :length => 16
20
+ end
21
+
22
+ class Exponent < SignedSmallInteger
23
+ value_type :length => 32
24
+ end
25
+
26
+ class FactId < AutoCounter
27
+ value_type
28
+ end
29
+
30
+ class FactTypeId < AutoCounter
31
+ value_type
32
+ end
33
+
34
+ class Frequency < UnsignedInteger
35
+ value_type :length => 32
36
+ end
37
+
38
+ class InstanceId < AutoCounter
39
+ value_type
40
+ end
41
+
42
+ class Length < UnsignedInteger
43
+ value_type :length => 32
44
+ end
45
+
46
+ class Name < String
47
+ value_type :length => 64
48
+ end
49
+
50
+ class Numerator < Decimal
51
+ value_type
52
+ end
53
+
54
+ class Ordinal < UnsignedSmallInteger
55
+ value_type :length => 32
56
+ end
57
+
58
+ class ReadingText < String
59
+ value_type :length => 256
60
+ end
61
+
62
+ class RingType < String
63
+ value_type
64
+ end
65
+
66
+ class RoleSequenceId < AutoCounter
67
+ value_type
68
+ end
69
+
70
+ class Scale < UnsignedInteger
71
+ value_type :length => 32
72
+ end
73
+
74
+ class UnitId < AutoCounter
75
+ value_type
76
+ end
77
+
78
+ class Value < String
79
+ value_type :length => 256
80
+ end
81
+
82
+ class ValueRestrictionId < AutoCounter
83
+ value_type
84
+ end
85
+
86
+ class Bound
87
+ identified_by :value, :is_inclusive
88
+ maybe :is_inclusive
89
+ has_one :value # See Value.all_bound
90
+ end
91
+
92
+ class Coefficient
93
+ identified_by :numerator, :denominator
94
+ has_one :denominator # See Denominator.all_coefficient
95
+ maybe :is_precise
96
+ has_one :numerator # See Numerator.all_coefficient
97
+ end
98
+
99
+ class Constraint
100
+ identified_by :constraint_id
101
+ one_to_one :constraint_id # See ConstraintId.constraint
102
+ has_one :enforcement # See Enforcement.all_constraint
103
+ has_one :name # See Name.all_constraint
104
+ has_one :vocabulary # See Vocabulary.all_constraint
105
+ end
106
+
107
+ class Fact
108
+ identified_by :fact_id
109
+ one_to_one :fact_id # See FactId.fact
110
+ has_one :fact_type # See FactType.all_fact
111
+ has_one :population # See Population.all_fact
112
+ end
113
+
114
+ class FactType
115
+ identified_by :fact_type_id
116
+ one_to_one :fact_type_id # See FactTypeId.fact_type
117
+ end
118
+
119
+ class Instance
120
+ identified_by :instance_id
121
+ has_one :concept # See Concept.all_instance
122
+ one_to_one :instance_id # See InstanceId.instance
123
+ has_one :population # See Population.all_instance
124
+ has_one :value # See Value.all_instance
125
+ end
126
+
127
+ class PresenceConstraint < Constraint
128
+ maybe :is_mandatory
129
+ maybe :is_preferred_identifier
130
+ has_one :max_frequency, Frequency # See Frequency.all_presence_constraint_by_max_frequency
131
+ has_one :min_frequency, Frequency # See Frequency.all_presence_constraint_by_min_frequency
132
+ has_one :role_sequence # See RoleSequence.all_presence_constraint
133
+ end
134
+
135
+ class Reading
136
+ identified_by :fact_type, :ordinal
137
+ has_one :fact_type # See FactType.all_reading
138
+ has_one :ordinal # See Ordinal.all_reading
139
+ has_one :reading_text # See ReadingText.all_reading
140
+ has_one :role_sequence # See RoleSequence.all_reading
141
+ end
142
+
143
+ class RingConstraint < Constraint
144
+ has_one :other_role, "Role" # See Role.all_ring_constraint_by_other_role
145
+ has_one :ring_type # See RingType.all_ring_constraint
146
+ has_one :role # See Role.all_ring_constraint
147
+ end
148
+
149
+ class RoleSequence
150
+ identified_by :role_sequence_id
151
+ one_to_one :role_sequence_id # See RoleSequenceId.role_sequence
152
+ end
153
+
154
+ class RoleValue
155
+ identified_by :instance, :fact
156
+ has_one :fact # See Fact.all_role_value
157
+ has_one :instance # See Instance.all_role_value
158
+ has_one :population # See Population.all_role_value
159
+ has_one :role # See Role.all_role_value
160
+ end
161
+
162
+ class SetConstraint < Constraint
163
+ end
164
+
165
+ class SubsetConstraint < SetConstraint
166
+ has_one :subset_role_sequence, RoleSequence # See RoleSequence.all_subset_constraint_by_subset_role_sequence
167
+ has_one :superset_role_sequence, RoleSequence # See RoleSequence.all_subset_constraint_by_superset_role_sequence
168
+ end
169
+
170
+ class Unit
171
+ identified_by :unit_id
172
+ has_one :coefficient # See Coefficient.all_unit
173
+ maybe :is_fundamental
174
+ has_one :name # See Name.all_unit
175
+ one_to_one :unit_id # See UnitId.unit
176
+ end
177
+
178
+ class UnitBasis
179
+ identified_by :base_unit, :derived_unit
180
+ has_one :base_unit, Unit # See Unit.all_unit_basis_by_base_unit
181
+ has_one :derived_unit, Unit # See Unit.all_unit_basis_by_derived_unit
182
+ has_one :exponent # See Exponent.all_unit_basis
183
+ end
184
+
185
+ class ValueRange
186
+ identified_by :minimum_bound, :maximum_bound
187
+ has_one :maximum_bound, Bound # See Bound.all_value_range_by_maximum_bound
188
+ has_one :minimum_bound, Bound # See Bound.all_value_range_by_minimum_bound
189
+ end
190
+
191
+ class ValueRestriction
192
+ identified_by :value_restriction_id
193
+ one_to_one :value_restriction_id # See ValueRestrictionId.value_restriction
194
+ end
195
+
196
+ class AllowedRange
197
+ identified_by :value_range, :value_restriction
198
+ has_one :value_range # See ValueRange.all_allowed_range
199
+ has_one :value_restriction # See ValueRestriction.all_allowed_range
200
+ end
201
+
202
+ class Vocabulary
203
+ identified_by :name
204
+ one_to_one :name # See Name.vocabulary
205
+ end
206
+
207
+ class Import
208
+ identified_by :imported_vocabulary, :vocabulary
209
+ has_one :imported_vocabulary, Vocabulary # See Vocabulary.all_import_by_imported_vocabulary
210
+ has_one :vocabulary # See Vocabulary.all_import
211
+ end
212
+
213
+ class Feature
214
+ identified_by :name, :vocabulary
215
+ has_one :name # See Name.all_feature
216
+ has_one :vocabulary # See Vocabulary.all_feature
217
+ end
218
+
219
+ class Correspondence
220
+ identified_by :imported_feature, :import
221
+ has_one :import # See Import.all_correspondence
222
+ has_one :imported_feature, Feature # See Feature.all_correspondence_by_imported_feature
223
+ has_one :local_feature, Feature # See Feature.all_correspondence_by_local_feature
224
+ end
225
+
226
+ class Population
227
+ identified_by :vocabulary, :name
228
+ has_one :name # See Name.all_population
229
+ has_one :vocabulary # See Vocabulary.all_population
230
+ end
231
+
232
+ class SetComparisonConstraint < SetConstraint
233
+ end
234
+
235
+ class SetComparisonRoles
236
+ identified_by :set_comparison_constraint, :role_sequence
237
+ has_one :role_sequence # See RoleSequence.all_set_comparison_roles
238
+ has_one :set_comparison_constraint # See SetComparisonConstraint.all_set_comparison_roles
239
+ end
240
+
241
+ class SetEqualityConstraint < SetComparisonConstraint
242
+ end
243
+
244
+ class SetExclusionConstraint < SetComparisonConstraint
245
+ maybe :is_mandatory
246
+ end
247
+
248
+ class Alias < Feature
249
+ end
250
+
251
+ class Concept < Feature
252
+ maybe :is_independent
253
+ maybe :is_personal
254
+ end
255
+
256
+ class Role
257
+ identified_by :fact_type, :ordinal, :concept
258
+ has_one :concept # See Concept.all_role
259
+ has_one :fact_type # See FactType.all_role
260
+ has_one :ordinal # See Ordinal.all_role
261
+ has_one :role_name, Name # See Name.all_role_by_role_name
262
+ has_one :role_value_restriction, ValueRestriction # See ValueRestriction.all_role_by_role_value_restriction
263
+ end
264
+
265
+ class RoleRef
266
+ identified_by :role_sequence, :ordinal
267
+ has_one :ordinal # See Ordinal.all_role_ref
268
+ has_one :role # See Role.all_role_ref
269
+ has_one :role_sequence # See RoleSequence.all_role_ref
270
+ has_one :leading_adjective, Adjective # See Adjective.all_role_ref_by_leading_adjective
271
+ has_one :trailing_adjective, Adjective # See Adjective.all_role_ref_by_trailing_adjective
272
+ end
273
+
274
+ class JoinPath
275
+ identified_by :role_ref, :join_step
276
+ has_one :join_step, Ordinal # See Ordinal.all_join_path_by_join_step
277
+ has_one :role_ref # See RoleRef.all_join_path
278
+ has_one :concept # See Concept.all_join_path
279
+ has_one :input_role, Role # See Role.all_join_path_by_input_role
280
+ has_one :output_role, Role # See Role.all_join_path_by_output_role
281
+ end
282
+
283
+ class EntityType < Concept
284
+ one_to_one :fact_type # See FactType.entity_type
285
+ end
286
+
287
+ class TypeInheritance < FactType
288
+ identified_by :subtype, :supertype
289
+ has_one :subtype, EntityType # See EntityType.all_type_inheritance_by_subtype
290
+ has_one :supertype, EntityType # See EntityType.all_type_inheritance_by_supertype
291
+ maybe :provides_identification
292
+ end
293
+
294
+ class ValueType < Concept
295
+ has_one :length # See Length.all_value_type
296
+ has_one :scale # See Scale.all_value_type
297
+ has_one :supertype, ValueType # See ValueType.all_value_type_by_supertype
298
+ has_one :unit # See Unit.all_value_type
299
+ has_one :value_restriction # See ValueRestriction.all_value_type
300
+ end
301
+
302
+ end
303
+ end