activefacts-compositions 1.9.6 → 1.9.8

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9dd27f8a8f6a05f883483391f31e2a026b9a52b4
4
- data.tar.gz: cc0355b8f29a879c654d7e36e542a95045e71994
3
+ metadata.gz: c3f30aa198a18c360d4fee63de36a3764df7d799
4
+ data.tar.gz: 28db19dcd307a9ab3ab1e7a50fada7023651d6e6
5
5
  SHA512:
6
- metadata.gz: 2dc13c0b861580a23517fe1fe50f6dd4d8b88a42fb7ee15827119992c090172386efb984855a7ecf81f97a682e3439201f718bd1ae7fcb7aeeb3420317c86230
7
- data.tar.gz: 45854d64978972f11839794e6c6fe0cd38a0e09c0c13f66081e9a0580cd4d01503350f144946dd22174b06530c0394b72632f5ac0fa660ba1ddf706e036bcb55
6
+ metadata.gz: 0b179e371a8f8b47a308d5790c6a21e4dec2c490eb7bd76da9bab58a0c8ae201fbf50c27a6a6b882e3395a9118b75ab16568353e076a17be1fd5197c4b78ae2f
7
+ data.tar.gz: cb28e3eb273607b31fb7e55fa2e826a5cc965764345a4b80c8096531d33be0dc97e05b7103424b5afd9bee1bc68d7fb9d51341a87967909eba52eaddd1964ed7
data/.gitignore CHANGED
@@ -12,3 +12,4 @@
12
12
  *.rej
13
13
  *.orig
14
14
  *.diff
15
+ actual
data/Rakefile CHANGED
@@ -21,3 +21,36 @@ task :bump do
21
21
  )
22
22
  end
23
23
  end
24
+
25
+ desc "Display differences between expected and actual from the last test run"
26
+ task :actual do
27
+ system <<-END
28
+ for actual in `find spec -type d -name actual`
29
+ do
30
+ base=`dirname "$actual"`
31
+ files="`ls $base/actual/* 2>/dev/null`"
32
+ if [ x"$files" != x"" ]
33
+ then
34
+ echo "=================================== $base ==================================="
35
+ diff -rub $base/expected/ $base/actual |grep -v '^Only in .*expected'
36
+ fi
37
+ done
38
+ END
39
+ end
40
+
41
+ desc "Accept the last actual test output, making it expected for the next test run"
42
+ task :accept do
43
+ system <<-END
44
+ for actual_dir in `find spec -type d -name actual`
45
+ do
46
+ base=`dirname "$actual_dir"`
47
+ expected=`cd "$base/expected"; git ls-files`
48
+ actual=`cd "$base/actual"; ls $expected 2>/dev/null`
49
+ if [ x"$actual" != x"" ]
50
+ then
51
+ echo "Accepting $actual"
52
+ (cd "$base/actual"; mv $actual ../expected)
53
+ fi
54
+ done
55
+ END
56
+ end
@@ -19,14 +19,14 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ["lib"]
21
21
 
22
- spec.add_development_dependency "bundler", ">= 1.10", "~> 1.10.6"
22
+ spec.add_development_dependency "bundler", ">= 1.11"
23
23
  spec.add_development_dependency "rake", "~> 10.0"
24
24
  spec.add_development_dependency "rspec", "~> 3.3"
25
25
 
26
26
  spec.add_development_dependency "activefacts", "~> 1", ">= 1.8"
27
27
 
28
- spec.add_runtime_dependency("activefacts-api", "~> 1", ">= 1.9.5")
29
- spec.add_runtime_dependency("activefacts-metamodel", "~> 1", ">= 1.9.6")
28
+ spec.add_runtime_dependency("activefacts-api", "~> 1", ">= 1.9.11")
29
+ spec.add_runtime_dependency("activefacts-metamodel", "~> 1", ">= 1.9.10")
30
30
  spec.add_runtime_dependency "tracing", "~> 2", ">= 2.0.6"
31
31
 
32
32
  spec.add_runtime_dependency "activefacts-cql", "~> 1", ">= 1.8"
@@ -5,111 +5,168 @@
5
5
  # Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
6
6
  #
7
7
  ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
8
- require 'bundler/setup' # Set up gems listed in the Gemfile.
9
8
  $:.unshift File.dirname(File.expand_path(__FILE__))+"/../lib"
10
9
 
10
+ require 'pathname'
11
11
  require 'activefacts/loadable'
12
12
  require 'activefacts/metamodel'
13
13
  require 'activefacts/compositions'
14
14
  require 'activefacts/generator'
15
15
 
16
- # Parse options into a hash, and values for each option into a hash
17
- options = {}
18
- while ARGV[0] =~ /^-/
19
- option, value = ARGV.shift.split(/=/, 2)
20
- options[option.sub(/^-*/,'')] =
21
- (value =~ /,/ ? value.split(',') : Array(value)).
22
- inject({}){|h,s| k, v = s.split(/=/, 2); h[k] = v || true; h }
23
- end
16
+ class SchemaCompositor
17
+ attr_reader :options
18
+ attr_reader :compositors
19
+ attr_reader :generators
24
20
 
25
- # Load and enumerate all available compositors:
26
- compositions_path = "activefacts/compositions"
27
- Loadable.new(compositions_path).
28
- enumerate.
29
- select do |filename|
30
- begin
31
- require(pathname = compositions_path+"/"+filename)
32
- rescue LoadError => e
33
- rescue Exception => e
34
- puts "Can't load #{pathname}: #{e.class}: #{e.message} #{e.backtrace[0]}"
21
+ # Parse options into a hash, and values for each option into a hash
22
+ def initialize argv
23
+ @options = {}
24
+ while argv[0] =~ /^-/
25
+ option, value = argv.shift.split(/=/, 2)
26
+ @options[option.sub(/^-*/,'')] =
27
+ (value =~ /,/ ? value.split(',') : Array(value)).
28
+ inject({}){|h,s| k, v = s.split(/=/, 2); h[k] = v || true; h }
29
+ end
35
30
  end
36
- end
37
31
 
38
- # Load and enumerate all available generators
39
- generators_path = "activefacts/generator"
40
- Loadable.new(generators_path).
41
- enumerate.
42
- select do |filename|
43
- begin
44
- require(pathname = generators_path+"/"+filename)
45
- rescue LoadError => e
46
- rescue Exception => e
47
- puts "Can't load #{pathname}: #{e.class}: #{e.message} #{e.backtrace[0]}"
32
+ # Load and enumerate all available modules in this path
33
+ def enumerate_available path
34
+ Loadable.new(path).
35
+ enumerate.
36
+ select do |filename|
37
+ begin
38
+ require(pathname = path+"/"+filename)
39
+ rescue LoadError => e
40
+ rescue Exception => e
41
+ $stderr.puts "Can't load #{pathname}: #{e.class}: #{e.message} #{e.backtrace[0]}"
42
+ end
43
+ end
48
44
  end
49
- end
50
45
 
51
- if options['help']
52
- puts "Available compositors:\n\t#{ActiveFacts::Compositions.compositors.keys.sort*"\n\t"}\n\n"
53
- puts "Available generators:\n\t#{ActiveFacts::Generators.generators.keys.sort*"\n\t"}\n\n"
54
- exit
55
- end
56
-
57
- # Arrange the requested compositors and generators:
58
- compositors = []
59
- generators = []
60
- options.clone.each do |option, mode|
61
- if action = ActiveFacts::Compositions.compositors[option]
62
- options.delete(option)
63
- compositors << [action, mode]
64
- elsif action = ActiveFacts::Generators.generators[option]
65
- options.delete(option)
66
- generators << [action, mode]
67
- end
68
- if mode && mode['help']
69
- puts "REVISIT: Help for #{option} is not yet available"
46
+ def arrange_actions
47
+ # Arrange the requested compositors and generators:
48
+ @compositors = []
49
+ @generators = []
50
+ @options.clone.each do |option, mode|
51
+ if action = ActiveFacts::Compositions.compositors[option]
52
+ options.delete(option)
53
+ check_options(action, mode)
54
+ @compositors << [action, mode]
55
+ elsif action = ActiveFacts::Generators.generators[option]
56
+ options.delete(option)
57
+ check_options(action, mode)
58
+ @generators << [action, mode]
59
+ else
60
+ $stderr.puts "Action --#{option} is not recognised"
61
+ exit 1
62
+ end
63
+ if mode && mode['help']
64
+ puts "Help for #{option} is not yet available"
65
+ end
66
+ end
70
67
  end
71
- end
72
68
 
73
- # Process each input file:
74
- ARGV.each do |arg|
75
- filename, input_options = *arg.split(/=/, 2)
69
+ def process_files argv
70
+ # Process each input file:
71
+ argv.each do |arg|
72
+ filename, input_options = *arg.split(/=/, 2)
76
73
 
77
- # Load the correct file type input method
78
- pathname, basename, extension = * /(?:(.*)[\/\\])?(.*)\.([^.]*)$/.match(filename).captures
79
- input_handler = "activefacts/input/#{extension}"
80
- require input_handler
74
+ # Load the correct file type input method
75
+ pathname, basename, extension = * /(?:(.*)[\/\\])?(.*)\.([^.]*)$/.match(filename).captures
76
+ input_handler = "activefacts/input/#{extension}"
77
+ require input_handler
81
78
 
82
- input_class = extension.upcase
83
- input_klass = ActiveFacts::Input.const_get(input_class.to_sym)
84
- raise "Expected #{input_handler} to define #{input_class}" unless input_klass
79
+ input_class = extension.upcase
80
+ input_klass = ActiveFacts::Input.const_get(input_class.to_sym)
81
+ raise "Expected #{input_handler} to define #{input_class}" unless input_klass
85
82
 
86
- # Read the input file:
87
- vocabulary =
88
- if input_klass
89
- begin
90
- input_klass.readfile(filename, *input_options)
91
- rescue => e
92
- $stderr.puts "#{e.message}"
93
- if trace :exception
94
- $stderr.puts "\t#{e.backtrace*"\n\t"}"
95
- else
96
- $stderr.puts "\t#{e.backtrace[0]}"
83
+ # Read the input file:
84
+ vocabulary =
85
+ if input_klass
86
+ begin
87
+ input_klass.readfile(filename, *input_options)
88
+ rescue => e
89
+ $stderr.puts "#{e.message}"
90
+ if trace :exception
91
+ $stderr.puts "\t#{e.backtrace*"\n\t"}"
92
+ else
93
+ $stderr.puts "\t#{e.backtrace[0]}"
94
+ end
95
+ exit 1
96
+ end
97
+ end
98
+ exit 0 unless vocabulary
99
+ vocabulary.finalise unless vocabulary == true
100
+
101
+ # Run each compositor
102
+ @compositors.each do |compositor_klass, mode|
103
+ compositor = compositor_klass.new(vocabulary.constellation, basename, mode||{})
104
+ compositor.generate
105
+
106
+ # Run each generator
107
+ @generators.each do |generator, mode|
108
+ output = generator.new(compositor.composition, mode||{}).generate
109
+ puts output if output
97
110
  end
98
- exit 1
99
111
  end
100
112
  end
101
- exit 0 unless vocabulary
102
- vocabulary.finalise unless vocabulary == true
103
-
104
- # Run each compositor
105
- compositors.each do |compositor_klass, mode|
106
- compositor = compositor_klass.new(vocabulary.constellation, basename, mode||{})
107
- compositor.generate
108
-
109
- # Run each generator
110
- generators.each do |generator, mode|
111
- output = generator.new(compositor.composition, mode||{}).generate
112
- puts output if output
113
+ end
114
+
115
+ def action_name action
116
+ action.name.sub(/ActiveFacts::[^:]+::/,'').gsub(/::/,'/').downcase
117
+ end
118
+
119
+ def display_options action, stream = $stdout
120
+ options = action.options
121
+ name = action.name.sub(/ActiveFacts::[^:]+::/,'').gsub(/::/,'/').downcase
122
+ if options.empty?
123
+ stream.puts "There are no options for --#{action_name action}"
124
+ else
125
+ stream.puts "Options for --#{name} (say e.g. --#{action_name action}=option1=value,option2)"
126
+ options.keys.sort.each do |key|
127
+ type, description = *options[key]
128
+ tag =
129
+ key.to_s +
130
+ case type
131
+ when NilClass,'Boolean', TrueClass
132
+ ''
133
+ when Numeric
134
+ ' num'
135
+ when Pathname
136
+ ' file'
137
+ else
138
+ ' str'
139
+ end
140
+
141
+ stream.puts "\t#{tag}#{' '*(24-tag.size)}#{description}"
142
+ end
113
143
  end
114
144
  end
145
+
146
+ # Ensure that the options provided are supported by the action
147
+ def check_options action, mode
148
+ if mode['help']
149
+ display_options(action)
150
+ exit
151
+ end
152
+ options = action.options
153
+ unsupported = mode.keys.select{|k| !options.has_key?(k.to_sym)}
154
+ return if unsupported.empty?
155
+ $stderr.puts "Action --#{action_name action} does not support #{unsupported.size >1 ? 'these options' : 'this option'}: #{unsupported*', '}"
156
+ display_options(action, $stderr)
157
+ exit 1
158
+ end
115
159
  end
160
+
161
+ sc = SchemaCompositor.new(ARGV)
162
+ sc.enumerate_available('activefacts/compositions')
163
+ sc.enumerate_available('activefacts/generator')
164
+ if sc.options['help']
165
+ puts "Available compositors:\n\t#{ActiveFacts::Compositions.compositors.keys.sort*"\n\t"}\n\n"
166
+ puts "Available generators:\n\t#{ActiveFacts::Generators.generators.keys.sort*"\n\t"}\n\n"
167
+ puts "To get help for a particular action, follow it by =help, e.g. --relational=help"
168
+ exit
169
+ end
170
+
171
+ sc.arrange_actions
172
+ sc.process_files ARGV
@@ -1,7 +1,7 @@
1
1
  ### Composition
2
2
  # ActiveFacts Compositions, Binary Compositor.
3
3
  #
4
- # Fans of RDF will like this one.
4
+ # Fans of RDF will like this one.
5
5
  #
6
6
  # Copyright (c) 2015 Clifford Heath. Read the LICENSE file.
7
7
  #
@@ -10,23 +10,27 @@ require "activefacts/compositions"
10
10
  module ActiveFacts
11
11
  module Compositions
12
12
  class Binary < Compositor
13
+ def self.options
14
+ {}
15
+ end
16
+
13
17
  def generate
14
- super
18
+ super
15
19
 
16
- trace :binary!, "Constructing Binary Composition" do
17
- @binary_mappings.keys.sort_by(&:name).each do |object_type|
18
- mapping = @binary_mappings[object_type]
19
- mapping.re_rank
20
- composite = @constellation.Composite(mapping, composition: @composition)
21
- end
22
- end
20
+ trace :binary!, "Constructing Binary Composition" do
21
+ @binary_mappings.keys.sort_by(&:name).each do |object_type|
22
+ mapping = @binary_mappings[object_type]
23
+ mapping.re_rank
24
+ composite = @constellation.Composite(mapping, composition: @composition)
25
+ end
26
+ end
23
27
 
24
- trace :binary!, "Full binary composition" do
25
- @binary_mappings.keys.sort_by(&:name).each do |object_type|
26
- mapping = @binary_mappings[object_type]
27
- mapping.show_trace
28
- end
29
- end
28
+ trace :binary!, "Full binary composition" do
29
+ @binary_mappings.keys.sort_by(&:name).each do |object_type|
30
+ mapping = @binary_mappings[object_type]
31
+ mapping.show_trace
32
+ end
33
+ end
30
34
 
31
35
  end
32
36
  end
@@ -1,13 +1,13 @@
1
1
  #
2
2
  # ActiveFacts Compositions, Fundamental Compositor
3
3
  #
4
- # All Compositors derive from this one, which can calculate the basic binary bi-directional mapping
4
+ # All Compositors derive from this one, which can calculate the basic binary bi-directional mapping
5
5
  #
6
- # The term "reference" used here means either an Absorption
7
- # (one direction of a binary fact type relating two object types),
8
- # or an Indicator (for a unary fact type).
6
+ # The term "reference" used here means either an Absorption
7
+ # (one direction of a binary fact type relating two object types),
8
+ # or an Indicator (for a unary fact type).
9
9
  #
10
- # n-ary fact types and other objectified fact types are factored out by using the associated LinkFactTypes.
10
+ # n-ary fact types and other objectified fact types are factored out by using the associated LinkFactTypes.
11
11
  #
12
12
  # Copyright (c) 2015 Clifford Heath. Read the LICENSE file.
13
13
  #
@@ -15,141 +15,142 @@ require "activefacts/metamodel"
15
15
 
16
16
  module ActiveFacts
17
17
  module Compositions
18
- private
19
- MM = ActiveFacts::Metamodel
20
18
  class Compositor
21
19
  attr_reader :options, :name, :composition
22
20
 
21
+ def self.options
22
+ {}
23
+ end
24
+
23
25
  def initialize constellation, name, options = {}
24
- @constellation = constellation
25
- @name = name
26
- @options = options
27
- $stderr.puts "Unknown options: #{options.inspect}" unless options.empty?
26
+ @constellation = constellation
27
+ @name = name
28
+ @options = options
28
29
  end
29
30
 
30
31
  # Generate all Mappings into @binary_mappings for a binary composition of all ObjectTypes in this constellation
31
32
  def generate
32
- # Retract an existing composition by this name
33
- if existing = @constellation.Name[[@name]] and
34
- @composition = existing.composition
35
- @composition.all_composite.to_a.each{|composite| composite.retract}
36
- @composition.retract
37
- end
38
-
39
- @composition = @constellation.Composition(:new, :name => @name)
40
- preload_preferred_identifiers
41
- populate_references
33
+ # Retract an existing composition by this name
34
+ if existing = @constellation.Name[[@name]] and
35
+ @composition = existing.composition
36
+ @composition.all_composite.to_a.each{|composite| composite.retract}
37
+ @composition.retract
38
+ end
39
+
40
+ @composition = @constellation.Composition(:new, :name => @name)
41
+ preload_preferred_identifiers
42
+ populate_references
42
43
  end
43
44
 
44
45
  private
45
46
  # Preferred identifiers are cached, but the process produces trace output
46
47
  # that appears in the "tutti" mode used in testing. This precludes that.
47
48
  def preload_preferred_identifiers
48
- @constellation.EntityType.map{|k, et| et.preferred_identifier }
49
+ @constellation.EntityType.map{|k, et| et.preferred_identifier }
49
50
  end
50
51
 
51
52
  def populate_reference object_type, role
52
- parent = @binary_mappings[role.object_type]
53
-
54
- return if role.fact_type.all_role.size > 2
55
- if role.fact_type.all_role.size != 1
56
- counterpart = role.counterpart
57
- rt = role_type(counterpart)
58
- if rt == :many_many
59
- raise "Fact type must be objectified: #{role.fact_type.default_reading}"
60
- end
61
-
62
- a = @constellation.Absorption(
63
- :new,
64
- name: role_name(counterpart),
65
- parent: parent,
66
- object_type: counterpart.object_type,
67
- parent_role: role,
68
- child_role: counterpart
69
- )
70
- # Populate the absorption/reverse_absorption (putting the "many" or optional side as reverse)
71
- if r = @component_by_fact[role.fact_type]
72
- # Second occurrence of this fact type, set the direction:
73
- if a.is_preferred_direction
74
- a.reverse_absorption = r
75
- else # Set this as the reverse absorption
76
- a.forward_absorption = r
77
- end
78
- else
79
- # First occurrence of this fact type
80
- @component_by_fact[role.fact_type] = a
81
- end
82
- else # It's an indicator
83
- a = @constellation.Indicator(
84
- :new,
85
- name: role.name,
86
- parent: parent,
87
- role: role
88
- )
89
- @component_by_fact[role.fact_type] = a # For completeness, in case a subclass uses it
90
- end
91
- trace :binarize, "Populating #{a.inspect}"
53
+ parent = @binary_mappings[role.object_type]
54
+
55
+ return if role.fact_type.all_role.size > 2
56
+ if role.fact_type.all_role.size != 1
57
+ counterpart = role.counterpart
58
+ rt = role_type(counterpart)
59
+ if rt == :many_many
60
+ raise "Fact type must be objectified: #{role.fact_type.default_reading}"
61
+ end
62
+
63
+ a = @constellation.Absorption(
64
+ :new,
65
+ name: role_name(counterpart),
66
+ parent: parent,
67
+ object_type: counterpart.object_type,
68
+ parent_role: role,
69
+ child_role: counterpart
70
+ )
71
+ # Populate the absorption/reverse_absorption (putting the "many" or optional side as reverse)
72
+ if r = @component_by_fact[role.fact_type]
73
+ # Second occurrence of this fact type, set the direction:
74
+ if a.is_preferred_direction
75
+ a.reverse_absorption = r
76
+ else # Set this as the reverse absorption
77
+ a.forward_absorption = r
78
+ end
79
+ else
80
+ # First occurrence of this fact type
81
+ @component_by_fact[role.fact_type] = a
82
+ end
83
+ else # It's an indicator
84
+ a = @constellation.Indicator(
85
+ :new,
86
+ name: role.name,
87
+ parent: parent,
88
+ role: role
89
+ )
90
+ @component_by_fact[role.fact_type] = a # For completeness, in case a subclass uses it
91
+ end
92
+ trace :binarize, "Populating #{a.inspect}"
92
93
  end
93
94
 
94
95
  def populate_references
95
- # A table of Mappings by object type, with a default Mapping for each:
96
- @binary_mappings = Hash.new do |h, object_type|
97
- h[object_type] = @constellation.Mapping(
98
- :new,
99
- name: object_type.name,
100
- object_type: object_type
101
- )
102
- end
103
- @component_by_fact = {}
104
-
105
- @constellation.ObjectType.each do |key, object_type|
106
- trace :binarize, "Populating possible absorptions for #{object_type.name}" do
107
- @binary_mappings[object_type] # Ensure we create the top Mapping even if it has no references
108
-
109
- object_type.all_role.each do |role|
110
- # Exclude base roles in objectified fact types (unless unary); just use link fact types
111
- next if role.fact_type.entity_type && role.fact_type.all_role.size != 1
112
- next if role.variable # REVISIT: Continue to ignore roles in derived fact types?
113
- populate_reference object_type, role
114
- end
115
- if object_type.is_a?(ActiveFacts::Metamodel::ValueType)
116
- # This requires a change in the metamodel to use TypeInheritance for ValueTypes
117
- if object_type.supertype
118
- trace :binarize, "REVISIT: Eliding supertype #{object_type.supertype.name} for #{object_type.name}"
119
- end
120
- object_type.all_value_type_as_supertype.each do |subtype|
121
- trace :binarize, "REVISIT: Eliding subtype #{subtype.name} for #{object_type.name}"
122
- end
123
- end
124
- end
125
- end
96
+ # A table of Mappings by object type, with a default Mapping for each:
97
+ @binary_mappings = Hash.new do |h, object_type|
98
+ h[object_type] = @constellation.Mapping(
99
+ :new,
100
+ name: object_type.name,
101
+ object_type: object_type
102
+ )
103
+ end
104
+ @component_by_fact = {}
105
+
106
+ @constellation.ObjectType.each do |key, object_type|
107
+ trace :binarize, "Populating possible absorptions for #{object_type.name}" do
108
+ @binary_mappings[object_type] # Ensure we create the top Mapping even if it has no references
109
+
110
+ object_type.all_role.each do |role|
111
+ # Exclude base roles in objectified fact types (unless unary); just use link fact types
112
+ next if role.fact_type.entity_type && role.fact_type.all_role.size != 1
113
+ next if role.variable # REVISIT: Continue to ignore roles in derived fact types?
114
+ populate_reference object_type, role
115
+ end
116
+ if object_type.is_a?(ActiveFacts::Metamodel::ValueType)
117
+ # This requires a change in the metamodel to use TypeInheritance for ValueTypes
118
+ if object_type.supertype
119
+ trace :binarize, "REVISIT: Eliding supertype #{object_type.supertype.name} for #{object_type.name}"
120
+ end
121
+ object_type.all_value_type_as_supertype.each do |subtype|
122
+ trace :binarize, "REVISIT: Eliding subtype #{subtype.name} for #{object_type.name}"
123
+ end
124
+ end
125
+ end
126
+ end
126
127
  end
127
128
 
128
129
  def role_name role
129
- # if role.fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance) && role == role.fact_type.subtype_role
130
- # return "Is "+role.object_type.name
131
- # end
132
- role = role.base_role unless role.base_role.fact_type.all_role.size == 1
133
- String::Words.new(role.preferred_reference.role_name(nil)).capwords*' '
130
+ # if role.fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance) && role == role.fact_type.subtype_role
131
+ # return "Is "+role.object_type.name
132
+ # end
133
+ role = role.base_role unless role.base_role.fact_type.all_role.size == 1
134
+ String::Words.new(role.preferred_reference.role_name(nil)).capwords*' '
134
135
  end
135
136
 
136
137
  def role_type role
137
- fact_type = role.fact_type
138
- if fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance)
139
- return role.object_type == fact_type.supertype ? :supertype : :subtype
140
- end
141
-
142
- return :unary if fact_type.all_role.size == 1
143
-
144
- if fact_type.is_a?(ActiveFacts::Metamodel::LinkFactType)
145
- # Prevent an unnecessary from-1 search:
146
- from_1 = true
147
- # Change the to_1 search to detect a one-to-one:
148
- role = fact_type.implying_role
149
- fact_type = role.fact_type
150
- end
151
-
152
- # List the UCs on this fact type:
138
+ fact_type = role.fact_type
139
+ if fact_type.is_a?(ActiveFacts::Metamodel::TypeInheritance)
140
+ return role.object_type == fact_type.supertype ? :supertype : :subtype
141
+ end
142
+
143
+ return :unary if fact_type.all_role.size == 1
144
+
145
+ if fact_type.is_a?(ActiveFacts::Metamodel::LinkFactType)
146
+ # Prevent an unnecessary from-1 search:
147
+ from_1 = true
148
+ # Change the to_1 search to detect a one-to-one:
149
+ role = fact_type.implying_role
150
+ fact_type = role.fact_type
151
+ end
152
+
153
+ # List the UCs on this fact type:
153
154
  all_uniqueness_constraints =
154
155
  fact_type.all_role.map do |fact_role|
155
156
  fact_role.all_role_ref.map do |rr|
@@ -159,7 +160,7 @@ module ActiveFacts
159
160
  end
160
161
  end.flatten.uniq
161
162
 
162
- # It's to-1 if a UC exists over exactly this role:
163
+ # It's to-1 if a UC exists over exactly this role:
163
164
  to_1 =
164
165
  all_uniqueness_constraints.
165
166
  detect do |c|
@@ -186,16 +187,16 @@ module ActiveFacts
186
187
 
187
188
  # Display the primitive binary mapping:
188
189
  def show_references
189
- trace :composition, "Displaying the mappings:" do
190
- @binary_mappings.keys.sort_by(&:name).each do |object_type|
191
- mapping = @binary_mappings[object_type]
192
- trace :composition, "#{object_type.name}" do
193
- mapping.all_member.each do |component|
194
- trace :composition, component.inspect
195
- end
196
- end
197
- end
198
- end
190
+ trace :composition, "Displaying the mappings:" do
191
+ @binary_mappings.keys.sort_by(&:name).each do |object_type|
192
+ mapping = @binary_mappings[object_type]
193
+ trace :composition, "#{object_type.name}" do
194
+ mapping.all_member.each do |component|
195
+ trace :composition, component.inspect
196
+ end
197
+ end
198
+ end
199
+ end
199
200
  end
200
201
 
201
202
  end