activefacts 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|