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.
- data/History.txt +4 -0
- data/Manifest.txt +83 -0
- data/README.rdoc +81 -0
- data/Rakefile +41 -0
- data/bin/afgen +46 -0
- data/bin/cql +52 -0
- data/examples/CQL/Address.cql +46 -0
- data/examples/CQL/Blog.cql +54 -0
- data/examples/CQL/CompanyDirectorEmployee.cql +51 -0
- data/examples/CQL/Death.cql +16 -0
- data/examples/CQL/Genealogy.cql +95 -0
- data/examples/CQL/Marriage.cql +18 -0
- data/examples/CQL/Metamodel.cql +238 -0
- data/examples/CQL/MultiInheritance.cql +19 -0
- data/examples/CQL/OilSupply.cql +47 -0
- data/examples/CQL/Orienteering.cql +108 -0
- data/examples/CQL/PersonPlaysGame.cql +17 -0
- data/examples/CQL/SchoolActivities.cql +31 -0
- data/examples/CQL/SimplestUnary.cql +12 -0
- data/examples/CQL/SubtypePI.cql +32 -0
- data/examples/CQL/Warehousing.cql +99 -0
- data/examples/CQL/WindowInRoomInBldg.cql +22 -0
- data/lib/activefacts.rb +10 -0
- data/lib/activefacts/api.rb +25 -0
- data/lib/activefacts/api/concept.rb +384 -0
- data/lib/activefacts/api/constellation.rb +106 -0
- data/lib/activefacts/api/entity.rb +239 -0
- data/lib/activefacts/api/instance.rb +54 -0
- data/lib/activefacts/api/numeric.rb +158 -0
- data/lib/activefacts/api/role.rb +94 -0
- data/lib/activefacts/api/standard_types.rb +67 -0
- data/lib/activefacts/api/support.rb +59 -0
- data/lib/activefacts/api/value.rb +122 -0
- data/lib/activefacts/api/vocabulary.rb +120 -0
- data/lib/activefacts/cql.rb +31 -0
- data/lib/activefacts/cql/CQLParser.treetop +104 -0
- data/lib/activefacts/cql/Concepts.treetop +112 -0
- data/lib/activefacts/cql/DataTypes.treetop +66 -0
- data/lib/activefacts/cql/Expressions.treetop +113 -0
- data/lib/activefacts/cql/FactTypes.treetop +185 -0
- data/lib/activefacts/cql/Language/English.treetop +92 -0
- data/lib/activefacts/cql/LexicalRules.treetop +169 -0
- data/lib/activefacts/cql/Rakefile +6 -0
- data/lib/activefacts/cql/parser.rb +88 -0
- data/lib/activefacts/generate/absorption.rb +87 -0
- data/lib/activefacts/generate/cql.rb +441 -0
- data/lib/activefacts/generate/cql/html.rb +397 -0
- data/lib/activefacts/generate/null.rb +19 -0
- data/lib/activefacts/generate/ordered.rb +557 -0
- data/lib/activefacts/generate/ruby.rb +326 -0
- data/lib/activefacts/generate/sql/server.rb +164 -0
- data/lib/activefacts/generate/text.rb +21 -0
- data/lib/activefacts/input/cql.rb +1268 -0
- data/lib/activefacts/input/orm.rb +926 -0
- data/lib/activefacts/persistence.rb +1 -0
- data/lib/activefacts/persistence/composition.rb +653 -0
- data/lib/activefacts/support.rb +51 -0
- data/lib/activefacts/version.rb +3 -0
- data/lib/activefacts/vocabulary.rb +6 -0
- data/lib/activefacts/vocabulary/extensions.rb +343 -0
- data/lib/activefacts/vocabulary/metamodel.rb +303 -0
- data/script/txt2html +71 -0
- data/spec/absorption_spec.rb +95 -0
- data/spec/api/autocounter.rb +82 -0
- data/spec/api/constellation.rb +130 -0
- data/spec/api/entity_type.rb +101 -0
- data/spec/api/instance.rb +428 -0
- data/spec/api/roles.rb +122 -0
- data/spec/api/value_type.rb +112 -0
- data/spec/api_spec.rb +14 -0
- data/spec/cql_cql_spec.rb +58 -0
- data/spec/cql_parse_spec.rb +31 -0
- data/spec/cql_ruby_spec.rb +60 -0
- data/spec/cql_sql_spec.rb +54 -0
- data/spec/cql_symbol_tables_spec.rb +259 -0
- data/spec/cql_unit_spec.rb +336 -0
- data/spec/cqldump_spec.rb +169 -0
- data/spec/norma_cql_spec.rb +48 -0
- data/spec/norma_ruby_spec.rb +50 -0
- data/spec/norma_sql_spec.rb +45 -0
- data/spec/norma_tables_spec.rb +94 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +10 -0
- 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,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
|