activefacts 0.7.0 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/README.rdoc +0 -3
  2. data/Rakefile +7 -5
  3. data/bin/afgen +5 -2
  4. data/bin/cql +3 -2
  5. data/examples/CQL/Genealogy.cql +3 -3
  6. data/examples/CQL/Metamodel.cql +10 -7
  7. data/examples/CQL/MultiInheritance.cql +2 -1
  8. data/examples/CQL/OilSupply.cql +4 -4
  9. data/examples/CQL/Orienteering.cql +2 -2
  10. data/lib/activefacts.rb +2 -1
  11. data/lib/activefacts/api.rb +21 -2
  12. data/lib/activefacts/api/concept.rb +52 -39
  13. data/lib/activefacts/api/constellation.rb +8 -6
  14. data/lib/activefacts/api/entity.rb +41 -37
  15. data/lib/activefacts/api/instance.rb +5 -3
  16. data/lib/activefacts/api/numeric.rb +28 -21
  17. data/lib/activefacts/api/role.rb +29 -43
  18. data/lib/activefacts/api/standard_types.rb +8 -3
  19. data/lib/activefacts/api/support.rb +4 -4
  20. data/lib/activefacts/api/value.rb +9 -3
  21. data/lib/activefacts/api/vocabulary.rb +17 -7
  22. data/lib/activefacts/cql.rb +10 -7
  23. data/lib/activefacts/cql/CQLParser.treetop +6 -0
  24. data/lib/activefacts/cql/Concepts.treetop +32 -26
  25. data/lib/activefacts/cql/DataTypes.treetop +6 -0
  26. data/lib/activefacts/cql/Expressions.treetop +6 -0
  27. data/lib/activefacts/cql/FactTypes.treetop +6 -0
  28. data/lib/activefacts/cql/Language/English.treetop +9 -3
  29. data/lib/activefacts/cql/LexicalRules.treetop +6 -0
  30. data/lib/activefacts/cql/Rakefile +8 -0
  31. data/lib/activefacts/cql/parser.rb +4 -2
  32. data/lib/activefacts/generate/absorption.rb +20 -28
  33. data/lib/activefacts/generate/cql.rb +28 -16
  34. data/lib/activefacts/generate/cql/html.rb +327 -321
  35. data/lib/activefacts/generate/null.rb +7 -3
  36. data/lib/activefacts/generate/oo.rb +19 -15
  37. data/lib/activefacts/generate/ordered.rb +457 -461
  38. data/lib/activefacts/generate/ruby.rb +12 -4
  39. data/lib/activefacts/generate/sql/server.rb +42 -10
  40. data/lib/activefacts/generate/text.rb +7 -3
  41. data/lib/activefacts/input/cql.rb +55 -28
  42. data/lib/activefacts/input/orm.rb +32 -22
  43. data/lib/activefacts/persistence.rb +5 -0
  44. data/lib/activefacts/persistence/columns.rb +66 -32
  45. data/lib/activefacts/persistence/foreignkey.rb +29 -5
  46. data/lib/activefacts/persistence/index.rb +57 -25
  47. data/lib/activefacts/persistence/reference.rb +65 -30
  48. data/lib/activefacts/persistence/tables.rb +28 -17
  49. data/lib/activefacts/support.rb +8 -0
  50. data/lib/activefacts/version.rb +7 -1
  51. data/lib/activefacts/vocabulary.rb +4 -2
  52. data/lib/activefacts/vocabulary/extensions.rb +12 -10
  53. data/lib/activefacts/vocabulary/metamodel.rb +24 -23
  54. data/spec/api/autocounter.rb +2 -2
  55. data/spec/api/entity_type.rb +2 -2
  56. data/spec/api/instance.rb +61 -30
  57. data/spec/api/roles.rb +9 -9
  58. data/spec/cql_parse_spec.rb +1 -0
  59. data/spec/norma_tables_spec.rb +3 -3
  60. metadata +8 -4
@@ -1,14 +1,18 @@
1
1
  #
2
- # Generate text output for ActiveFacts vocabularies.
2
+ # ActiveFacts Generators.
3
+ # Generate *no* output for ActiveFacts vocabularies; i.e. just a stub
3
4
  #
4
- # Copyright (c) 2007 Clifford Heath. Read the LICENSE file.
5
- # Author: Clifford Heath.
5
+ # Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
6
6
  #
7
7
  require 'activefacts/persistence'
8
8
 
9
9
  module ActiveFacts
10
10
  module Generate
11
+ # Generate nothing from an ActiveFacts vocabulary. This is useful to check the file can be read ok.
12
+ # Invoke as
13
+ # afgen --null <file>.cql
11
14
  class NULL
15
+ private
12
16
  def initialize(vocabulary, *options)
13
17
  @vocabulary = vocabulary
14
18
  @vocabulary = @vocabulary.Vocabulary.values[0] if ActiveFacts::API::Constellation === @vocabulary
@@ -1,14 +1,16 @@
1
1
  #
2
- # OO Generation support for the ActiveFacts API from an ActiveFacts vocabulary.
3
- # Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
2
+ # ActiveFacts Generators.
3
+ # Base class for generators of class libraries in any object-oriented language that supports the ActiveFacts API.
4
+ #
5
+ # Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
4
6
  #
5
7
  require 'activefacts/vocabulary'
6
8
  require 'activefacts/generate/ordered'
7
9
 
8
10
  module ActiveFacts
9
-
10
11
  module Generate
11
- class OO < OrderedDumper
12
+ # Base class for generators of object-oriented class libraries for an ActiveFacts vocabulary.
13
+ class OO < OrderedDumper #:nodoc:
12
14
  include Metamodel
13
15
 
14
16
  def constraints_dump(constraints_used)
@@ -23,13 +25,12 @@ module ActiveFacts
23
25
 
24
26
  def roles_dump(o)
25
27
  o.all_role.
28
+ select{|role|
29
+ role.fact_type.all_role.size <= 2
30
+ }.
26
31
  sort_by{|role|
27
- other_role = role.fact_type.all_role[role.fact_type.all_role[0] != role ? 0 : -1]
28
- other_role ? preferred_role_name(other_role) : ""
29
- #puts "\t#{role.fact_type.describe(other_role)} by #{p}"
32
+ preferred_role_name(role.fact_type.all_role.select{|r2| r2 != role}[0] || role)
30
33
  }.each{|role|
31
- fact_type = role.fact_type
32
- next if fact_type.all_role.size > 2
33
34
  role_dump(role)
34
35
  }
35
36
  end
@@ -49,8 +50,7 @@ module ActiveFacts
49
50
  return
50
51
  end
51
52
 
52
- other_role_number = fact_type.all_role[0] == role ? 1 : 0
53
- other_role = fact_type.all_role[other_role_number]
53
+ other_role = fact_type.all_role.select{|r| r != role}[0]
54
54
  other_role_name = preferred_role_name(other_role)
55
55
  other_player = other_role.concept
56
56
 
@@ -80,9 +80,13 @@ module ActiveFacts
80
80
 
81
81
  # Find role name:
82
82
  role_method = preferred_role_name(role)
83
- by = other_role_name != other_player.name.snakecase ? "_by_#{other_role_name}" : ""
83
+ as = other_role_name != other_player.name.snakecase ? "_as_#{other_role_name}" : ""
84
84
  other_role_method = one_to_one ? role_method : "all_"+role_method
85
- other_role_method += by
85
+ # puts "---"+role.role_name if role.role_name
86
+ if other_role_name != other_player.name.snakecase and
87
+ role_method == role.concept.name.snakecase
88
+ other_role_method += "_as_#{other_role_name}"
89
+ end
86
90
 
87
91
  role_name = role_method
88
92
  role_name = nil if role_name == role.concept.name.snakecase
@@ -134,9 +138,9 @@ module ActiveFacts
134
138
  preferred_role_name(role)
135
139
  }.each{|role|
136
140
  role_name = preferred_role_name(role)
137
- by = role_name != role.concept.name.snakecase ? "_by_#{role_name}" : ""
141
+ as = role_name != role.concept.name.snakecase ? "_as_#{role_name}" : ""
138
142
  raise "Fact #{fact.describe} type is not objectified" unless fact.entity_type
139
- other_role_method = "all_"+fact.entity_type.name.snakecase+by
143
+ other_role_method = "all_"+fact.entity_type.name.snakecase+as
140
144
  binary_dump(role, role_name, role.concept, false, nil, nil, other_role_method)
141
145
  }
142
146
  end
@@ -1,557 +1,553 @@
1
1
  #
2
- # Generator superclass for ActiveFacts vocabularies that performs sequencing to avoid forward references.
2
+ # ActiveFacts Generators.
3
+ # Generation support superclass that sequences entity types to avoid forward references.
3
4
  #
4
- # Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
5
+ # Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
5
6
  #
6
7
  require 'activefacts/api'
7
8
 
8
9
  module ActiveFacts
10
+ module Generate #:nodoc:
11
+ class OrderedDumper #:nodoc:
12
+ # Base class for generators of object-oriented class libraries for an ActiveFacts vocabulary.
13
+ include Metamodel
14
+
15
+ def initialize(vocabulary, *options)
16
+ @vocabulary = vocabulary
17
+ @vocabulary = @vocabulary.Vocabulary.values[0] if ActiveFacts::API::Constellation === @vocabulary
18
+ options.each{|option| set_option(option) }
19
+ end
9
20
 
10
- class OrderedDumper #:nodoc:
11
- include Metamodel
12
-
13
- def initialize(vocabulary, *options)
14
- @vocabulary = vocabulary
15
- @vocabulary = @vocabulary.Vocabulary.values[0] if ActiveFacts::API::Constellation === @vocabulary
16
- options.each{|option| set_option(option) }
17
- end
18
-
19
- def set_option(option)
20
- end
21
+ def set_option(option)
22
+ end
21
23
 
22
- def puts(*a)
23
- @out.puts *a
24
- end
24
+ def puts(*a)
25
+ @out.puts *a
26
+ end
25
27
 
26
- def print(*a)
27
- @out.print *a
28
- end
28
+ def print(*a)
29
+ @out.print *a
30
+ end
29
31
 
30
- def generate(out = $>)
31
- @out = out
32
- vocabulary_start(@vocabulary)
33
-
34
- build_indices
35
- @concept_types_dumped = {}
36
- @fact_types_dumped = {}
37
- value_types_dump()
38
- entity_types_dump()
39
- fact_types_dump()
40
- constraints_dump(@constraints_used)
41
- vocabulary_end
42
- end
32
+ def generate(out = $>)
33
+ @out = out
34
+ vocabulary_start(@vocabulary)
35
+
36
+ build_indices
37
+ @concept_types_dumped = {}
38
+ @fact_types_dumped = {}
39
+ value_types_dump()
40
+ entity_types_dump()
41
+ fact_types_dump()
42
+ constraints_dump(@constraints_used)
43
+ vocabulary_end
44
+ end
43
45
 
44
- def build_indices
45
- @presence_constraints_by_fact = Hash.new{ |h, k| h[k] = [] }
46
- @ring_constraints_by_fact = Hash.new{ |h, k| h[k] = [] }
47
-
48
- @vocabulary.all_constraint.each { |c|
49
- case c
50
- when PresenceConstraint
51
- fact_types = c.role_sequence.all_role_ref.map{|rr| rr.role.fact_type}.uniq # All fact types spanned by this constraint
52
- if fact_types.size == 1 # There's only one, save it:
53
- # debug "Single-fact constraint on #{fact_types[0].fact_type_id}: #{c.name}"
54
- (@presence_constraints_by_fact[fact_types[0]] ||= []) << c
46
+ def build_indices
47
+ @presence_constraints_by_fact = Hash.new{ |h, k| h[k] = [] }
48
+ @ring_constraints_by_fact = Hash.new{ |h, k| h[k] = [] }
49
+
50
+ @vocabulary.all_constraint.each { |c|
51
+ case c
52
+ when PresenceConstraint
53
+ fact_types = c.role_sequence.all_role_ref.map{|rr| rr.role.fact_type}.uniq # All fact types spanned by this constraint
54
+ if fact_types.size == 1 # There's only one, save it:
55
+ # debug "Single-fact constraint on #{fact_types[0].fact_type_id}: #{c.name}"
56
+ (@presence_constraints_by_fact[fact_types[0]] ||= []) << c
57
+ end
58
+ when RingConstraint
59
+ (@ring_constraints_by_fact[c.role.fact_type] ||= []) << c
60
+ else
61
+ # debug "Found unhandled constraint #{c.class} #{c.name}"
55
62
  end
56
- when RingConstraint
57
- (@ring_constraints_by_fact[c.role.fact_type] ||= []) << c
58
- else
59
- # debug "Found unhandled constraint #{c.class} #{c.name}"
60
- end
61
- }
62
- @constraints_used = {}
63
- end
64
-
65
- def value_types_dump
66
- done_banner = false
67
- @vocabulary.all_feature.sort_by{|o| o.name}.each{|o|
68
- next unless ValueType === o
63
+ }
64
+ @constraints_used = {}
65
+ end
69
66
 
70
- value_type_banner unless done_banner
71
- done_banner = true
67
+ def value_types_dump
68
+ done_banner = false
69
+ @vocabulary.all_feature.sort_by{|o| o.name}.each{|o|
70
+ next unless ValueType === o
72
71
 
73
- value_type_dump(o)
74
- @concept_types_dumped[o] = true
75
- }
76
- value_type_end if done_banner
77
- end
72
+ value_type_banner unless done_banner
73
+ done_banner = true
78
74
 
79
- # Try to dump entity types in order of name, but we need
80
- # to dump ETs before they're referenced in preferred ids
81
- # if possible (it's not always, there may be loops!)
82
- def entity_types_dump
83
- # Build hash tables of precursors and followers to use:
84
- precursors, followers = *build_entity_dependencies
85
-
86
- done_banner = false
87
- sorted = @vocabulary.all_feature.select{|o| EntityType === o and !o.fact_type }.sort_by{|o| o.name}
88
- panic = nil
89
- while true do
90
- count_this_pass = 0
91
- skipped_this_pass = 0
92
- sorted.each{|o|
93
- next if @concept_types_dumped[o] # Already done
94
-
95
- # Can we do this yet?
96
- if (o != panic and # We don't *have* to do it (panic mode)
97
- (p = precursors[o]) and # There might be...
98
- p.size > 0) # precursors - still blocked
99
- skipped_this_pass += 1
100
- next
101
- end
75
+ value_type_dump(o)
76
+ @concept_types_dumped[o] = true
77
+ }
78
+ value_type_end if done_banner
79
+ end
102
80
 
103
- entity_type_banner unless done_banner
104
- done_banner = true
81
+ # Try to dump entity types in order of name, but we need
82
+ # to dump ETs before they're referenced in preferred ids
83
+ # if possible (it's not always, there may be loops!)
84
+ def entity_types_dump
85
+ # Build hash tables of precursors and followers to use:
86
+ precursors, followers = *build_entity_dependencies
87
+
88
+ done_banner = false
89
+ sorted = @vocabulary.all_feature.select{|o| EntityType === o and !o.fact_type }.sort_by{|o| o.name}
90
+ panic = nil
91
+ while true do
92
+ count_this_pass = 0
93
+ skipped_this_pass = 0
94
+ sorted.each{|o|
95
+ next if @concept_types_dumped[o] # Already done
96
+
97
+ # Can we do this yet?
98
+ if (o != panic and # We don't *have* to do it (panic mode)
99
+ (p = precursors[o]) and # There might be...
100
+ p.size > 0) # precursors - still blocked
101
+ skipped_this_pass += 1
102
+ next
103
+ end
104
+
105
+ entity_type_banner unless done_banner
106
+ done_banner = true
105
107
 
106
- # We're going to emit o - remove it from precursors of others:
107
- (followers[o]||[]).each{|f|
108
- precursors[f] -= [o]
109
- }
110
- count_this_pass += 1
111
- panic = nil
108
+ # We're going to emit o - remove it from precursors of others:
109
+ (followers[o]||[]).each{|f|
110
+ precursors[f] -= [o]
111
+ }
112
+ count_this_pass += 1
113
+ panic = nil
112
114
 
113
- entity_type_dump(o)
114
- released_fact_types_dump(o)
115
+ entity_type_dump(o)
116
+ released_fact_types_dump(o)
115
117
 
116
- entity_type_group_end
117
- }
118
+ entity_type_group_end
119
+ }
118
120
 
119
- # Check that we made progress if there's any to make:
120
- if count_this_pass == 0 && skipped_this_pass > 0
121
- if panic # We were already panicing... what to do now?
122
- # This won't happen again unless the above code is changed to decide it can't dump "panic".
123
- raise "Unresolvable cycle of forward references: " +
124
- (bad = sorted.select{|o| EntityType === o && !@concept_types_dumped[o]}).map{|o| o.name }.inspect +
125
- ":\n\t" + bad.map{|o|
126
- o.name +
127
- ": " +
128
- precursors[o].map{|p| p.name}.uniq.inspect
129
- } * "\n\t" + "\n"
130
- else
131
- # Find the object that has the most followers and no fwd-ref'd supertypes:
132
- # This selection might be better if we allow PI roles to be fwd-ref'd...
133
- panic = sorted.
134
- select{|o| !@concept_types_dumped[o] }.
135
- sort_by{|o|
136
- f = followers[o] || [];
137
- o.supertypes.detect{|s| !@concept_types_dumped[s] } ? 0 : -f.size
138
- }[0]
139
- # debug "Panic mode, selected #{panic.name} next"
121
+ # Check that we made progress if there's any to make:
122
+ if count_this_pass == 0 && skipped_this_pass > 0
123
+ if panic # We were already panicing... what to do now?
124
+ # This won't happen again unless the above code is changed to decide it can't dump "panic".
125
+ raise "Unresolvable cycle of forward references: " +
126
+ (bad = sorted.select{|o| EntityType === o && !@concept_types_dumped[o]}).map{|o| o.name }.inspect +
127
+ ":\n\t" + bad.map{|o|
128
+ o.name +
129
+ ": " +
130
+ precursors[o].map{|p| p.name}.uniq.inspect
131
+ } * "\n\t" + "\n"
132
+ else
133
+ # Find the object that has the most followers and no fwd-ref'd supertypes:
134
+ # This selection might be better if we allow PI roles to be fwd-ref'd...
135
+ panic = sorted.
136
+ select{|o| !@concept_types_dumped[o] }.
137
+ sort_by{|o|
138
+ f = followers[o] || [];
139
+ o.supertypes.detect{|s| !@concept_types_dumped[s] } ? 0 : -f.size
140
+ }[0]
141
+ # debug "Panic mode, selected #{panic.name} next"
142
+ end
140
143
  end
141
- end
142
144
 
143
- break if skipped_this_pass == 0 # All done.
145
+ break if skipped_this_pass == 0 # All done.
144
146
 
147
+ end
145
148
  end
146
- end
147
149
 
148
- def entity_type_dump(o)
149
- @concept_types_dumped[o] = true
150
- pi = o.preferred_identifier
150
+ def entity_type_dump(o)
151
+ @concept_types_dumped[o] = true
152
+ pi = o.preferred_identifier
151
153
 
152
- supers = o.supertypes
153
- if (supers.size > 0)
154
- # Ignore identification by a supertype:
155
- pi = nil if pi && pi.role_sequence.all_role_ref[0].role.fact_type.is_a?(TypeInheritance)
156
- subtype_dump(o, supers, pi)
157
- else
158
- non_subtype_dump(o, pi)
154
+ supers = o.supertypes
155
+ if (supers.size > 0)
156
+ # Ignore identification by a supertype:
157
+ pi = nil if pi && pi.role_sequence.all_role_ref.detect{|rr| rr.role.fact_type.is_a?(TypeInheritance) }
158
+ subtype_dump(o, supers, pi)
159
+ else
160
+ non_subtype_dump(o, pi)
161
+ end
162
+ @constraints_used[pi] = true
159
163
  end
160
- @constraints_used[pi] = true
161
- end
162
164
 
163
- def identified_by(o, pi)
164
- # Different adjectives might be used for different readings.
165
- # Here, we must find the role_ref containing the adjectives that we need for each identifier,
166
- # which will be attached to the uniqueness constraint on this object in the binary FT that
167
- # attaches that identifying role.
168
- role_refs = pi.role_sequence.all_role_ref.sort_by{|role_ref| role_ref.ordinal}
169
-
170
- # We need to get the adjectives for the roles from the identifying fact's preferred readings:
171
- identifying_facts = role_refs.map{|rr| rr.role.fact_type }.uniq
172
- preferred_readings = identifying_facts.inject({}){|reading_hash, fact_type|
173
- pr = fact_type.preferred_reading
174
- reading_hash[fact_type] = pr
175
- reading_hash
176
- }
177
- #p identifying_facts.map{|f| f.preferred_reading }
165
+ def identified_by(o, pi)
166
+ # Different adjectives might be used for different readings.
167
+ # Here, we must find the role_ref containing the adjectives that we need for each identifier,
168
+ # which will be attached to the uniqueness constraint on this object in the binary FT that
169
+ # attaches that identifying role.
170
+ role_refs = pi.role_sequence.all_role_ref.sort_by{|role_ref| role_ref.ordinal}
171
+
172
+ # We need to get the adjectives for the roles from the identifying fact's preferred readings:
173
+ identifying_facts = role_refs.map{|rr| rr.role.fact_type }.uniq
174
+ preferred_readings = identifying_facts.inject({}){|reading_hash, fact_type|
175
+ pr = fact_type.preferred_reading
176
+ reading_hash[fact_type] = pr
177
+ reading_hash
178
+ }
179
+ #p identifying_facts.map{|f| f.preferred_reading }
178
180
 
179
- identifying_roles = role_refs.map(&:role)
180
- identification = identified_by_roles_and_facts(o, identifying_roles, identifying_facts, preferred_readings)
181
- #identifying_facts.each{|f| @fact_types_dumped[f] = true }
181
+ identifying_roles = role_refs.map(&:role)
182
+ identification = identified_by_roles_and_facts(o, identifying_roles, identifying_facts, preferred_readings)
183
+ #identifying_facts.each{|f| @fact_types_dumped[f] = true }
182
184
 
183
- identification
184
- end
185
+ identification
186
+ end
185
187
 
186
- def fact_readings_with_constraints(fact_type, fact_constraints = nil)
187
- define_role_names = true
188
- fact_constraints ||= @presence_constraints_by_fact[fact_type]
189
- readings = fact_type.all_reading_by_ordinal.inject([]) do |reading_array, reading|
190
- reading_array << expanded_reading(reading, fact_constraints, define_role_names)
188
+ def fact_readings_with_constraints(fact_type, fact_constraints = nil)
189
+ define_role_names = true
190
+ fact_constraints ||= @presence_constraints_by_fact[fact_type]
191
+ readings = fact_type.all_reading_by_ordinal.inject([]) do |reading_array, reading|
192
+ reading_array << expanded_reading(reading, fact_constraints, define_role_names)
191
193
 
192
- define_role_names = false # No need to define role names in subsequent readings
194
+ define_role_names = false # No need to define role names in subsequent readings
193
195
 
194
- reading_array
195
- end
196
+ reading_array
197
+ end
196
198
 
197
- readings
198
- end
199
+ readings
200
+ end
199
201
 
200
- def expanded_reading(reading, fact_constraints, define_role_names)
201
- # Find all role numbers in order of occurrence in this reading:
202
- role_refs = reading.role_sequence.all_role_ref.sort_by{|role_ref| role_ref.ordinal}
203
- role_numbers = reading.reading_text.scan(/\{(\d)\}/).flatten.map{|m| Integer(m) }
204
- roles = role_numbers.map{|m| role_refs[m].role }
205
- # debug "Considering #{reading.reading_text} having #{role_numbers.inspect}"
206
-
207
- # Find the constraints that constrain frequency over each role we can verbalise:
208
- frequency_constraints = []
209
- roles.each do |role|
210
- # Find a mandatory constraint that's *not* unique; this will need an extra reading
211
- role_is_first_in = reading.fact_type.all_reading.detect{|r|
212
- role == r.role_sequence.all_role_ref.sort_by{|role_ref|
213
- role_ref.ordinal
214
- }[0].role
215
- }
202
+ def expanded_reading(reading, fact_constraints, define_role_names)
203
+ # Find all role numbers in order of occurrence in this reading:
204
+ role_refs = reading.role_sequence.all_role_ref.sort_by{|role_ref| role_ref.ordinal}
205
+ role_numbers = reading.reading_text.scan(/\{(\d)\}/).flatten.map{|m| Integer(m) }
206
+ roles = role_numbers.map{|m| role_refs[m].role }
207
+ # debug "Considering #{reading.reading_text} having #{role_numbers.inspect}"
208
+
209
+ # Find the constraints that constrain frequency over each role we can verbalise:
210
+ frequency_constraints = []
211
+ roles.each do |role|
212
+ # Find a mandatory constraint that's *not* unique; this will need an extra reading
213
+ role_is_first_in = reading.fact_type.all_reading.detect{|r|
214
+ role == r.role_sequence.all_role_ref.sort_by{|role_ref|
215
+ role_ref.ordinal
216
+ }[0].role
217
+ }
216
218
 
217
- if (role == roles.last) # First role of the reading?
218
- # REVISIT: With a ternary, doing this on other than the last role can be ambiguous,
219
- # in case both the 2nd and 3rd roles have frequencies. Think some more!
219
+ if (role == roles.last) # First role of the reading?
220
+ # REVISIT: With a ternary, doing this on other than the last role can be ambiguous,
221
+ # in case both the 2nd and 3rd roles have frequencies. Think some more!
220
222
 
221
- constraint = fact_constraints.find{|c| # Find a UC that spans all other Roles
222
- # internal uniqueness constraints span all roles but one, the residual:
223
- PresenceConstraint === c &&
224
- !@constraints_used[c] && # Already verbalised
225
- roles-c.role_sequence.all_role_ref.map(&:role) == [role]
226
- }
227
- # Index the frequency implied by the constraint under the role position in the reading
228
- if constraint # Mark this constraint as "verbalised" so we don't do it again:
229
- @constraints_used[constraint] = true
223
+ constraint = fact_constraints.find{|c| # Find a UC that spans all other Roles
224
+ # internal uniqueness constraints span all roles but one, the residual:
225
+ PresenceConstraint === c &&
226
+ !@constraints_used[c] && # Already verbalised
227
+ roles-c.role_sequence.all_role_ref.map(&:role) == [role]
228
+ }
229
+ # Index the frequency implied by the constraint under the role position in the reading
230
+ if constraint # Mark this constraint as "verbalised" so we don't do it again:
231
+ @constraints_used[constraint] = true
232
+ end
233
+ frequency_constraints << show_frequency(role, constraint)
234
+ else
235
+ frequency_constraints << show_frequency(role, nil)
230
236
  end
231
- frequency_constraints << show_frequency(role, constraint)
232
- else
233
- frequency_constraints << show_frequency(role, nil)
234
237
  end
235
- end
236
238
 
237
- expanded = reading.expand(frequency_constraints, define_role_names)
239
+ expanded = reading.expand(frequency_constraints, define_role_names)
238
240
 
239
- if (ft_rings = @ring_constraints_by_fact[reading.fact_type]) &&
240
- (ring = ft_rings.detect{|rc| !@constraints_used[rc]})
241
- @constraints_used[ring] = true
242
- append_ring_to_reading(expanded, ring)
241
+ if (ft_rings = @ring_constraints_by_fact[reading.fact_type]) &&
242
+ (ring = ft_rings.detect{|rc| !@constraints_used[rc]})
243
+ @constraints_used[ring] = true
244
+ append_ring_to_reading(expanded, ring)
245
+ end
246
+ expanded
243
247
  end
244
- expanded
245
- end
246
248
 
247
- def show_frequency role, constraint
248
- constraint ? constraint.frequency : nil
249
- end
249
+ def show_frequency role, constraint
250
+ constraint ? constraint.frequency : nil
251
+ end
250
252
 
251
- def describe_fact_type(fact_type, highlight = nil)
252
- (fact_type.entity_type ? fact_type.entity_type.name : "")+
253
- describe_roles(fact_type.all_role, highlight)
254
- end
253
+ def describe_fact_type(fact_type, highlight = nil)
254
+ (fact_type.entity_type ? fact_type.entity_type.name : "")+
255
+ describe_roles(fact_type.all_role, highlight)
256
+ end
255
257
 
256
- def describe_roles(roles, highlight = nil)
257
- "("+
258
- roles.map{|role| role.concept.name + (role == highlight ? "*" : "")}*", "+
259
- ")"
260
- end
258
+ def describe_roles(roles, highlight = nil)
259
+ "("+
260
+ roles.map{|role| role.concept.name + (role == highlight ? "*" : "")}*", "+
261
+ ")"
262
+ end
261
263
 
262
- def describe_role_sequence(role_sequence)
263
- "("+
264
- role_sequence.all_role_ref.map{|role_ref| role_ref.role.concept.name }*", "+
265
- ")"
266
- end
264
+ def describe_role_sequence(role_sequence)
265
+ "("+
266
+ role_sequence.all_role_ref.map{|role_ref| role_ref.role.concept.name }*", "+
267
+ ")"
268
+ end
267
269
 
268
- # This returns an array of two hash tables each keyed by an EntityType.
269
- # The values of each hash entry are the precursors and followers (respectively) of that entity.
270
- def build_entity_dependencies
271
- @vocabulary.all_feature.inject([{},{}]) { |a, o|
272
- if EntityType === o && !o.fact_type
273
- precursor = a[0]
274
- follower = a[1]
275
- blocked = false
276
- pi = o.preferred_identifier
277
- if pi
278
- pi.role_sequence.all_role_ref.each{|rr|
279
- role = rr.role
280
- player = role.concept
281
- next unless EntityType === player
282
- # player is a precursor of o
283
- (precursor[o] ||= []) << player if (player != o)
284
- (follower[player] ||= []) << o if (player != o)
270
+ # This returns an array of two hash tables each keyed by an EntityType.
271
+ # The values of each hash entry are the precursors and followers (respectively) of that entity.
272
+ def build_entity_dependencies
273
+ @vocabulary.all_feature.inject([{},{}]) { |a, o|
274
+ if EntityType === o && !o.fact_type
275
+ precursor = a[0]
276
+ follower = a[1]
277
+ blocked = false
278
+ pi = o.preferred_identifier
279
+ if pi
280
+ pi.role_sequence.all_role_ref.each{|rr|
281
+ role = rr.role
282
+ player = role.concept
283
+ next unless EntityType === player
284
+ # player is a precursor of o
285
+ (precursor[o] ||= []) << player if (player != o)
286
+ (follower[player] ||= []) << o if (player != o)
287
+ }
288
+ end
289
+ # Supertypes are precursors too:
290
+ subtyping = o.all_type_inheritance_as_supertype
291
+ next a if subtyping.size == 0
292
+ subtyping.each{|ti|
293
+ # debug ti.class.roles.verbalise; debug "all_type_inheritance_as_supertype"; exit
294
+ s = ti.subtype
295
+ (precursor[s] ||= []) << o
296
+ (follower[o] ||= []) << s
285
297
  }
286
298
  end
287
- # Supertypes are precursors too:
288
- subtyping = o.all_type_inheritance_by_supertype
289
- next a if subtyping.size == 0
290
- subtyping.each{|ti|
291
- # debug ti.class.roles.verbalise; debug "all_type_inheritance_by_supertype"; exit
292
- s = ti.subtype
293
- (precursor[s] ||= []) << o
294
- (follower[o] ||= []) << s
295
- }
296
- end
297
- a
298
- }
299
- end
300
-
301
- # Dump all fact types for which all precursors (of which "o" is one) have been emitted:
302
- def released_fact_types_dump(o)
303
- roles = o.all_role
304
- begin
305
- progress = false
306
- roles.map(&:fact_type).uniq.select{|fact_type|
307
- # The fact type hasn't already been dumped but all its role players have
308
- !@fact_types_dumped[fact_type] &&
309
- !fact_type.all_role.detect{|r| !@concept_types_dumped[r.concept] }
310
- }.sort_by{|fact_type|
311
- fact_type_key(fact_type)
312
- }.each{|fact_type|
313
- fact_type_dump_with_dependents(fact_type)
314
- # Objectified Fact Types may release additional fact types
315
- roles += fact_type.entity_type.all_role if fact_type.entity_type
316
- progress = true
299
+ a
317
300
  }
318
- end while progress
319
- end
320
-
321
- def skip_fact_type(f)
322
- # REVISIT: There might be constraints we have to merge into the nested entity or subtype.
323
- # These will come up as un-handled constraints:
324
- pcs = @presence_constraints_by_fact[f]
325
- TypeInheritance === f ||
326
- (pcs && pcs.size > 0 && !pcs.detect{|c| !@constraints_used[c] })
327
- end
301
+ end
328
302
 
329
- # Dump one fact type.
330
- # Include as many as possible internal constraints in the fact type readings.
331
- def fact_type_dump_with_dependents(fact_type)
332
- @fact_types_dumped[fact_type] = true
333
- # debug "Trying to dump FT again" if @fact_types_dumped[fact_type]
334
- return if skip_fact_type(fact_type)
303
+ # Dump all fact types for which all precursors (of which "o" is one) have been emitted:
304
+ def released_fact_types_dump(o)
305
+ roles = o.all_role
306
+ begin
307
+ progress = false
308
+ roles.map(&:fact_type).uniq.select{|fact_type|
309
+ # The fact type hasn't already been dumped but all its role players have
310
+ !@fact_types_dumped[fact_type] &&
311
+ !fact_type.all_role.detect{|r| !@concept_types_dumped[r.concept] }
312
+ }.sort_by{|fact_type|
313
+ fact_type_key(fact_type)
314
+ }.each{|fact_type|
315
+ fact_type_dump_with_dependents(fact_type)
316
+ # Objectified Fact Types may release additional fact types
317
+ roles += fact_type.entity_type.all_role.sort_by{|role| role.ordinal} if fact_type.entity_type
318
+ progress = true
319
+ }
320
+ end while progress
321
+ end
335
322
 
336
- if (et = fact_type.entity_type) &&
337
- (pi = et.preferred_identifier) &&
338
- pi.role_sequence.all_role_ref[0].role.fact_type != fact_type
339
- # debug "Dumping objectified FT #{et.name} as an entity, non-fact PI"
340
- entity_type_dump(et)
341
- released_fact_types_dump(et)
342
- return
323
+ def skip_fact_type(f)
324
+ # REVISIT: There might be constraints we have to merge into the nested entity or subtype.
325
+ # These will come up as un-handled constraints:
326
+ pcs = @presence_constraints_by_fact[f]
327
+ TypeInheritance === f ||
328
+ (pcs && pcs.size > 0 && !pcs.detect{|c| !@constraints_used[c] })
343
329
  end
344
330
 
345
- fact_constraints = @presence_constraints_by_fact[fact_type]
331
+ # Dump one fact type.
332
+ # Include as many as possible internal constraints in the fact type readings.
333
+ def fact_type_dump_with_dependents(fact_type)
334
+ @fact_types_dumped[fact_type] = true
335
+ # debug "Trying to dump FT again" if @fact_types_dumped[fact_type]
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
+ # debug "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
346
 
347
- # debug "for fact type #{fact_type.to_s}, considering\n\t#{fact_constraints.map(&:to_s)*",\n\t"}"
348
- # debug "#{fact_type.name} has readings:\n\t#{fact_type.readings.map(&:name)*"\n\t"}"
349
- # debug "Dumping #{fact_type.fact_type_id} as a fact type"
347
+ fact_constraints = @presence_constraints_by_fact[fact_type]
350
348
 
351
- # Fact types that aren't nested have no names
352
- name = fact_type.entity_type && fact_type.entity_type.name
349
+ # debug "for fact type #{fact_type.to_s}, considering\n\t#{fact_constraints.map(&:to_s)*",\n\t"}"
350
+ # debug "#{fact_type.name} has readings:\n\t#{fact_type.readings.map(&:name)*"\n\t"}"
351
+ # debug "Dumping #{fact_type.fact_type_id} as a fact type"
353
352
 
354
- fact_type_dump(fact_type, name)
353
+ # Fact types that aren't nested have no names
354
+ name = fact_type.entity_type && fact_type.entity_type.name
355
355
 
356
- # REVISIT: Go through the residual constraints and re-process appropriate readings to show them
356
+ fact_type_dump(fact_type, name)
357
357
 
358
- @fact_types_dumped[fact_type] = true
359
- @concept_types_dumped[fact_type.entity_type] = true if fact_type.entity_type
360
- end
358
+ # REVISIT: Go through the residual constraints and re-process appropriate readings to show them
361
359
 
362
- # Arrange for objectified fact types to appear in order of name, after other fact types.
363
- # Facts are ordered alphabetically by the names of their role players,
364
- # then by preferred_reading (subtyping fact types have no preferred_reading).
365
- def fact_type_key(fact_type)
366
- role_names =
367
- if (pr = fact_type.preferred_reading)
368
- pr.role_sequence.
369
- all_role_ref.
370
- sort_by{|role_ref| role_ref.ordinal}.
371
- map{|role_ref| [ role_ref.leading_adjective, role_ref.role.concept.name, role_ref.trailing_adjective ].compact*"-" } +
372
- [pr.reading_text]
373
- else
374
- fact_type.all_role.map{|role| role.concept.name }
375
- end
360
+ @fact_types_dumped[fact_type] = true
361
+ @concept_types_dumped[fact_type.entity_type] = true if fact_type.entity_type
362
+ end
376
363
 
377
- (fact_type.entity_type ? [fact_type.entity_type.name] : [""]) + role_names
378
- end
364
+ # Arrange for objectified fact types to appear in order of name, after other fact types.
365
+ # Facts are ordered alphabetically by the names of their role players,
366
+ # then by preferred_reading (subtyping fact types have no preferred_reading).
367
+ def fact_type_key(fact_type)
368
+ role_names =
369
+ if (pr = fact_type.preferred_reading)
370
+ pr.role_sequence.
371
+ all_role_ref.
372
+ sort_by{|role_ref| role_ref.ordinal}.
373
+ map{|role_ref| [ role_ref.leading_adjective, role_ref.role.concept.name, role_ref.trailing_adjective ].compact*"-" } +
374
+ [pr.reading_text]
375
+ else
376
+ fact_type.all_role.map{|role| role.concept.name }
377
+ end
379
378
 
380
- def role_ref_key(role_ref)
381
- [ role_ref.leading_adjective, role_ref.role.concept.name, role_ref.trailing_adjective ].compact*"-"
382
- end
379
+ (fact_type.entity_type ? [fact_type.entity_type.name] : [""]) + role_names
380
+ end
383
381
 
384
- # Dump fact types.
385
- def fact_types_dump
386
- # REVISIT: Uniqueness on the LHS of a binary can be coded using "distinct"
387
-
388
- # The only fact types that can be remaining are those involving only value types,
389
- # since we dumped every fact type as soon as all relevant entities were dumped.
390
- # Iterate over all fact types of all value types, looking for these strays.
391
-
392
- done_banner = false
393
- fact_collection = @vocabulary.constellation.FactType
394
- fact_collection.keys.select{|fact_id|
395
- fact_type = fact_collection[fact_id]
396
- !(TypeInheritance === fact_type) and
397
- !@fact_types_dumped[fact_type] and
398
- !skip_fact_type(fact_type) and
399
- !fact_type.all_role.detect{|r| EntityType === r.concept }
400
- }.sort_by{|fact_id|
401
- fact_type = fact_collection[fact_id]
402
- fact_type_key(fact_type)
403
- }.each{|fact_id|
404
- fact_type = fact_collection[fact_id]
382
+ def role_ref_key(role_ref)
383
+ [ role_ref.leading_adjective, role_ref.role.concept.name, role_ref.trailing_adjective ].compact*"-"
384
+ end
405
385
 
406
- fact_type_banner unless done_banner
407
- done_banner = true
408
- fact_type_dump_with_dependents(fact_type)
409
- }
386
+ # Dump fact types.
387
+ def fact_types_dump
388
+ # REVISIT: Uniqueness on the LHS of a binary can be coded using "distinct"
389
+
390
+ # The only fact types that can be remaining are those involving only value types,
391
+ # since we dumped every fact type as soon as all relevant entities were dumped.
392
+ # Iterate over all fact types of all value types, looking for these strays.
393
+
394
+ done_banner = false
395
+ fact_collection = @vocabulary.constellation.FactType
396
+ fact_collection.keys.select{|fact_id|
397
+ fact_type = fact_collection[fact_id] and
398
+ !(TypeInheritance === fact_type) and
399
+ !@fact_types_dumped[fact_type] and
400
+ !skip_fact_type(fact_type) and
401
+ !fact_type.all_role.detect{|r| r.concept.is_a?(EntityType) }
402
+ }.sort_by{|fact_id|
403
+ fact_type = fact_collection[fact_id]
404
+ fact_type_key(fact_type)
405
+ }.each{|fact_id|
406
+ fact_type = fact_collection[fact_id]
407
+
408
+ fact_type_banner unless done_banner
409
+ done_banner = true
410
+ fact_type_dump_with_dependents(fact_type)
411
+ }
410
412
 
411
- # REVISIT: Find out why some fact types are missed during entity dumping:
412
- @vocabulary.constellation.FactType.values.select{|fact_type|
413
- !(TypeInheritance === fact_type)
414
- }.sort_by{|fact_type|
415
- fact_type_key(fact_type)
416
- }.each{|fact_type|
417
- next if @fact_types_dumped[fact_type]
418
- # debug "Not dumped #{fact_type.verbalise}(#{fact_type.all_role.map{|r| r.concept.name}*", "})"
419
- fact_type_banner unless done_banner
420
- done_banner = true
421
- fact_type_dump_with_dependents(fact_type)
422
- }
413
+ # REVISIT: Find out why some fact types are missed during entity dumping:
414
+ @vocabulary.constellation.FactType.values.select{|fact_type|
415
+ !(TypeInheritance === fact_type)
416
+ }.sort_by{|fact_type|
417
+ fact_type_key(fact_type)
418
+ }.each{|fact_type|
419
+ next if @fact_types_dumped[fact_type]
420
+ # debug "Not dumped #{fact_type.verbalise}(#{fact_type.all_role.map{|r| r.concept.name}*", "})"
421
+ fact_type_banner unless done_banner
422
+ done_banner = true
423
+ fact_type_dump_with_dependents(fact_type)
424
+ }
423
425
 
424
- fact_type_end if done_banner
425
- # unused = constraints - @constraints_used.keys
426
- # debug "residual constraints are\n\t#{unused.map(&:to_s)*",\n\t"}"
426
+ fact_type_end if done_banner
427
+ # unused = constraints - @constraints_used.keys
428
+ # debug "residual constraints are\n\t#{unused.map(&:to_s)*",\n\t"}"
427
429
 
428
- @constraints_used
429
- end
430
+ @constraints_used
431
+ end
430
432
 
431
- def fact_instances_dump
432
- @vocabulary.fact_types.each{|f|
433
- # Dump the instances:
434
- f.facts.each{|i|
435
- raise "REVISIT: Not dumping fact instances"
436
- debug "\t\t"+i.to_s
437
- }
438
- }
439
- end
433
+ def fact_instances_dump
434
+ @vocabulary.fact_types.each{|f|
435
+ # Dump the instances:
436
+ f.facts.each{|i|
437
+ raise "REVISIT: Not dumping fact instances"
438
+ debug "\t\t"+i.to_s
439
+ }
440
+ }
441
+ end
440
442
 
441
- def constraint_sort_key(c)
442
- case c
443
- when RingConstraint
444
- [1, c.ring_type, c.role.concept.name, c.other_role.concept.name, c.name||""]
445
- when SetComparisonConstraint
446
- [2, c.all_set_comparison_roles.map{|scrs| scrs.role_sequence.all_role_ref.map{|rr| role_ref_key(rr)}}, c.name||""]
447
- when SubsetConstraint
448
- [3, [c.superset_role_sequence, c.subset_role_sequence].map{|rs| rs.all_role_ref.map{|rr| role_ref_key(rr)}}, c.name||""]
449
- when PresenceConstraint
450
- [4, c.role_sequence.all_role_ref.map{|rr| role_ref_key(rr)}, c.name||""]
443
+ def constraint_sort_key(c)
444
+ case c
445
+ when RingConstraint
446
+ [1, c.ring_type, c.role.concept.name, c.other_role.concept.name, c.name||""]
447
+ when SetComparisonConstraint
448
+ [2, c.all_set_comparison_roles.map{|scrs| scrs.role_sequence.all_role_ref.map{|rr| role_ref_key(rr)}}, c.name||""]
449
+ when SubsetConstraint
450
+ [3, [c.superset_role_sequence, c.subset_role_sequence].map{|rs| rs.all_role_ref.map{|rr| role_ref_key(rr)}}, c.name||""]
451
+ when PresenceConstraint
452
+ [4, c.role_sequence.all_role_ref.map{|rr| role_ref_key(rr)}, c.name||""]
453
+ end
451
454
  end
452
- end
453
455
 
454
- def constraints_dump(except = {})
455
- heading = false
456
- @vocabulary.all_constraint.reject{|c| except[c]}.sort_by{ |c| constraint_sort_key(c) }.each do|c|
457
- # Skip some PresenceConstraints:
458
- if PresenceConstraint === c
459
- # Skip uniqueness constraints that cover all roles of a fact type, they're implicit
460
- role_refs = c.role_sequence.all_role_ref
461
- if role_refs.size == 0
462
- constraint_banner unless heading
463
- heading = true
464
- puts "PresenceConstraint without roles!"
465
- next
456
+ def constraints_dump(except = {})
457
+ heading = false
458
+ @vocabulary.all_constraint.reject{|c| except[c]}.sort_by{ |c| constraint_sort_key(c) }.each do|c|
459
+ # Skip some PresenceConstraints:
460
+ if PresenceConstraint === c
461
+ # Skip uniqueness constraints that cover all roles of a fact type, they're implicit
462
+ fact_types = c.role_sequence.all_role_ref.map{|rr| rr.role.fact_type}.uniq
463
+ next if fact_types.size == 1 &&
464
+ c.max_frequency == 1 && # Uniqueness
465
+ fact_types[0].all_role.size == c.role_sequence.all_role_ref.size
466
+
467
+ # Skip internal PresenceConstraints over TypeInheritances:
468
+ next if c.role_sequence.all_role_ref.size == 1 &&
469
+ TypeInheritance === fact_types[0]
466
470
  end
467
- fact_type0 = role_refs[0].role.fact_type
468
- next if c.max_frequency == 1 && # Uniqueness
469
- role_refs.size == fact_type0.all_role.size && # Same number of roles
470
- fact_type0.all_role.all?{|r| role_refs.map(&:role).include? r} # All present
471
-
472
- # Skip internal PresenceConstraints over TypeInheritances:
473
- next if TypeInheritance === fact_type0 &&
474
- !c.role_sequence.all_role_ref.detect{|rr| rr.role.fact_type != fact_type0 }
471
+
472
+ constraint_banner unless heading
473
+ heading = true
474
+
475
+ # Skip presence constraints on value types:
476
+ # next if ActiveFacts::PresenceConstraint === c &&
477
+ # ActiveFacts::ValueType === c.concept
478
+ constraint_dump(c)
475
479
  end
480
+ constraint_end if heading
481
+ end
476
482
 
477
- constraint_banner unless heading
478
- heading = true
483
+ def vocabulary_start(vocabulary)
484
+ debug "Should override vocabulary_start"
485
+ end
479
486
 
480
- # Skip presence constraints on value types:
481
- # next if ActiveFacts::PresenceConstraint === c &&
482
- # ActiveFacts::ValueType === c.concept
483
- constraint_dump(c)
487
+ def vocabulary_end
488
+ debug "Should override vocabulary_end"
484
489
  end
485
- constraint_end if heading
486
- end
487
490
 
488
- def vocabulary_start(vocabulary)
489
- debug "Should override vocabulary_start"
490
- end
491
+ def value_type_banner
492
+ debug "Should override value_type_banner"
493
+ end
491
494
 
492
- def vocabulary_end
493
- debug "Should override vocabulary_end"
494
- end
495
+ def value_type_end
496
+ debug "Should override value_type_end"
497
+ end
495
498
 
496
- def value_type_banner
497
- debug "Should override value_type_banner"
498
- end
499
+ def value_type_dump(o)
500
+ debug "Should override value_type_dump"
501
+ end
499
502
 
500
- def value_type_end
501
- debug "Should override value_type_end"
502
- end
503
+ def entity_type_banner
504
+ debug "Should override entity_type_banner"
505
+ end
503
506
 
504
- def value_type_dump(o)
505
- debug "Should override value_type_dump"
506
- end
507
+ def entity_type_group_end
508
+ debug "Should override entity_type_group_end"
509
+ end
507
510
 
508
- def entity_type_banner
509
- debug "Should override entity_type_banner"
510
- end
511
+ def non_subtype_dump(o, pi)
512
+ debug "Should override non_subtype_dump"
513
+ end
511
514
 
512
- def entity_type_group_end
513
- debug "Should override entity_type_group_end"
514
- end
515
+ def subtype_dump(o, supertypes, pi = nil)
516
+ debug "Should override subtype_dump"
517
+ end
515
518
 
516
- def non_subtype_dump(o, pi)
517
- debug "Should override non_subtype_dump"
518
- end
519
+ def append_ring_to_reading(reading, ring)
520
+ debug "Should override append_ring_to_reading"
521
+ end
519
522
 
520
- def subtype_dump(o, supertypes, pi = nil)
521
- debug "Should override subtype_dump"
522
- end
523
+ def fact_type_banner
524
+ debug "Should override fact_type_banner"
525
+ end
523
526
 
524
- def append_ring_to_reading(reading, ring)
525
- debug "Should override append_ring_to_reading"
526
- end
527
+ def fact_type_end
528
+ debug "Should override fact_type_end"
529
+ end
527
530
 
528
- def fact_type_banner
529
- debug "Should override fact_type_banner"
530
- end
531
+ def fact_type_dump(fact_type, name)
532
+ debug "Should override fact_type_dump"
533
+ end
531
534
 
532
- def fact_type_end
533
- debug "Should override fact_type_end"
534
- end
535
+ def constraint_banner
536
+ debug "Should override constraint_banner"
537
+ end
535
538
 
536
- def fact_type_dump(fact_type, name)
537
- debug "Should override fact_type_dump"
538
- end
539
+ def constraint_end
540
+ debug "Should override constraint_end"
541
+ end
539
542
 
540
- def constraint_banner
541
- debug "Should override constraint_banner"
542
- end
543
+ def constraint_dump(c)
544
+ debug "Should override constraint_dump"
545
+ end
543
546
 
544
- def constraint_end
545
- debug "Should override constraint_end"
546
547
  end
547
548
 
548
- def constraint_dump(c)
549
- debug "Should override constraint_dump"
549
+ def dump(vocabulary, out = $>)
550
+ OrderedDumper.new(vocabulary).dump(out)
550
551
  end
551
-
552
- end
553
-
554
- def dump(vocabulary, out = $>)
555
- OrderedDumper.new(vocabulary).dump(out)
556
552
  end
557
553
  end