activefacts 0.7.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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