glossarist 2.13.3 → 2.13.4

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
  SHA256:
3
- metadata.gz: 4ffd41dbfe184c1b47711cb7b38b10c136fca8fcdac813baf2f070f99b5f5212
4
- data.tar.gz: caaa34a425e82a8e79f20870ca4c49fcbe8b8bcb391ad1a5597f5c2904d3c242
3
+ metadata.gz: ebf6ec1d9cc3f2c1932fff4d389b19e60dff4846e3f82167fa6e13bef8347f7d
4
+ data.tar.gz: 2aee9b19e15588b9fc74a973d02406de96b1ed01ebefcdd7b87bc472d3b8d53b
5
5
  SHA512:
6
- metadata.gz: ef5b2c5cd5f4055b725399445d58246463c432b7d0a69ba2f81610b53dd9a5b5701963a5a7461add48da294d904f0faba5709c8bacfd79ac13415cecb61baa34
7
- data.tar.gz: 16eb1b43dd51bcc39c6da768a2edddbe33d01fd59af0ec972494c9a2f629f17a2b45ab120a218abd423605c7afa6ed54b405ec3088bd682804e9bc1bbad0c13d
6
+ metadata.gz: '09eeb3261b6e753a4e1690496f13db04053429318108d52a031963087a9c908f842a12802b310014874f78f5d47bfd3a54dd1672e610e0b55684133a82ec2331'
7
+ data.tar.gz: de663d1b6fe2581a17ae52e2fb69d2ea6accf6ca46f92be084ec603c5b8f0f3d614a5dbeaf5a20178bb8d08511ea046210ed09a183c9c35b0f9d462b0dcb62d6
data/config.yml CHANGED
@@ -212,17 +212,25 @@ completeness:
212
212
  - partial
213
213
 
214
214
  multiplicity:
215
- # ISO 704:2022 partitive member multiplicity. Encodes the diagram
216
- # line notation as structured data:
217
- # compulsory — 1 solid line (must exist in every instance)
218
- # optional — 1 dashed line (exists in some instances only)
219
- # compulsory_multiple2 solid lines (multiple must exist)
220
- # optional_multiple 2 dashed lines (multiple may exist)
221
- # compulsory_at_least_one — 1 solid + 1 dashed line (at least one must exist)
222
- # Default: compulsory.
223
- value:
224
- - compulsory
215
+ # MECE decomposition of ISO 704:2022 partitive member multiplicity.
216
+ # Two orthogonal dimensions replace the prior flat 5-value enum.
217
+ #
218
+ # presence (line style):
219
+ # required — solid line (must exist)
220
+ # optional — dashed line (may exist)
221
+ #
222
+ # count (line count):
223
+ # exactly_one — 1 line (exactly one instance)
224
+ # at_least_one — 1 solid + 1 dashed (at least one instance)
225
+ # multiple — 2 lines (multiple instances)
226
+ #
227
+ # Valid combinations (5): required+exactly_one, optional+exactly_one,
228
+ # required+multiple, optional+multiple, required+at_least_one.
229
+ # Invalid: optional+at_least_one (collapses to optional+multiple).
230
+ presence:
231
+ - required
225
232
  - optional
226
- - compulsory_multiple
227
- - optional_multiple
228
- - compulsory_at_least_one
233
+ count:
234
+ - exactly_one
235
+ - at_least_one
236
+ - multiple
@@ -37,6 +37,10 @@ module Glossarist
37
37
  # PartitiveRelation redesign (TODO.partitive-relation-v2).
38
38
  COMPLETENESS_VALUES = config.dig("completeness", "value").freeze
39
39
 
40
- MULTIPLICITY_VALUES = config.dig("multiplicity", "value").freeze
40
+ PARTITIVE_PRESENCE_VALUES =
41
+ config.dig("multiplicity", "presence").freeze
42
+
43
+ PARTITIVE_COUNT_VALUES =
44
+ config.dig("multiplicity", "count").freeze
41
45
  end
42
46
  end
@@ -5,13 +5,14 @@ require "lutaml/model"
5
5
  module Glossarist
6
6
  module Rdf
7
7
  # RDF view for V3::PartitiveMember. Emits a
8
- # gloss:PartitiveMember subject with ref, multiplicity, and
8
+ # gloss:PartitiveMember subject with ref, presence, count, and
9
9
  # is_delimiting properties.
10
10
  class GlossPartitiveMember < Lutaml::Model::Serializable
11
11
  attribute :ref_id, :string
12
12
  attribute :ref_source, :string
13
13
  attribute :ref_text, :string
14
- attribute :multiplicity, :string
14
+ attribute :presence, :string
15
+ attribute :count, :string
15
16
  attribute :is_delimiting, :boolean
16
17
 
17
18
  rdf do
@@ -27,8 +28,10 @@ module Glossarist
27
28
  to: :ref_id
28
29
  predicate :refText, namespace: Namespaces::GlossaristNamespace,
29
30
  to: :ref_text
30
- predicate :multiplicity, namespace: Namespaces::GlossaristNamespace,
31
- to: :multiplicity
31
+ predicate :presence, namespace: Namespaces::GlossaristNamespace,
32
+ to: :presence
33
+ predicate :count, namespace: Namespaces::GlossaristNamespace,
34
+ to: :count
32
35
  predicate :isDelimiting, namespace: Namespaces::GlossaristNamespace,
33
36
  to: :is_delimiting
34
37
  end
@@ -6,56 +6,88 @@ module Glossarist
6
6
  # a ConceptRef to the partitive concept plus ISO 704:2022
7
7
  # multiplicity and delimiting metadata.
8
8
  #
9
- # ISO 704:2022 partitive member notation:
9
+ # ISO 704:2022 partitive member notation uses two orthogonal
10
+ # dimensions (MECE decomposition):
10
11
  #
11
- # multiplicity (diagram line notation):
12
- # compulsory 1 solid line (must exist in every instance)
13
- # optional 1 dashed line (exists in some instances only)
14
- # compulsory_multiple — 2 solid lines (multiple must exist)
15
- # optional_multiple — 2 dashed lines (multiple may exist)
16
- # compulsory_at_least_one — 1 solid + 1 dashed line (≥1 must exist)
12
+ # presence (line style — solid vs dashed):
13
+ # required — solid line (must exist in every instance)
14
+ # optional — dashed line (may exist; exists in some instances)
17
15
  #
18
- # is_delimiting (orthogonal, bold 3x-width line in diagram):
19
- # A delimiting part behaves like a delimiting characteristic:
20
- # it distinguishes the comprehensive from coordinate concepts.
21
- # Example (ISO 704 §5.5.4.2.2): for "optomechanical mouse",
22
- # the delimiting parts are mouse ball, x/y-axis rollers,
23
- # infrared emitter/sensor they distinguish it from
24
- # "mechanical mouse" and "optical mouse". Mouse button is
25
- # NOT delimiting (all computer mice have buttons).
16
+ # count (line count how many):
17
+ # exactly_one — 1 line
18
+ # at_least_one 1 solid + 1 dashed
19
+ # multiple — 2 lines
20
+ #
21
+ # Valid combinations (5):
22
+ # required + exactly_one = compulsory (1 solid)
23
+ # optional + exactly_one = optional (1 dashed)
24
+ # required + multiple = compulsory_multiple (2 solid)
25
+ # optional + multiple = optional_multiple (2 dashed)
26
+ # required + at_least_one = compulsory_at_least_one (1 solid + 1 dashed)
27
+ #
28
+ # Invalid: optional + at_least_one (collapses to optional + multiple
29
+ # because "at least one, if present" = "zero or more" = optional_multiple).
30
+ #
31
+ # is_delimiting (orthogonal, bold 3x-width line in diagram):
32
+ # A delimiting part behaves like a delimiting characteristic:
33
+ # it distinguishes the comprehensive from coordinate concepts.
34
+ # Example (ISO 704 §5.5.4.2.2): for "optomechanical mouse",
35
+ # the delimiting parts are mouse ball, x/y-axis rollers,
36
+ # infrared emitter/sensor — they distinguish it from
37
+ # "mechanical mouse" and "optical mouse". Mouse button is
38
+ # NOT delimiting (all computer mice have buttons).
26
39
  class PartitiveMember < Lutaml::Model::Serializable
27
- DEFAULT_MULTIPLICITY = "compulsory"
40
+ DEFAULT_PRESENCE = "required"
41
+ DEFAULT_COUNT = "exactly_one"
28
42
 
29
43
  attribute :ref, ConceptRef
30
- attribute :multiplicity, :string,
31
- values: Glossarist::GlossaryDefinition::MULTIPLICITY_VALUES,
32
- default: -> { DEFAULT_MULTIPLICITY }
44
+ attribute :presence, :string,
45
+ values: Glossarist::GlossaryDefinition::PARTITIVE_PRESENCE_VALUES,
46
+ default: -> { DEFAULT_PRESENCE }
47
+ attribute :count, :string,
48
+ values: Glossarist::GlossaryDefinition::PARTITIVE_COUNT_VALUES,
49
+ default: -> { DEFAULT_COUNT }
33
50
  attribute :is_delimiting, :boolean, default: -> { false }
34
51
 
35
52
  key_value do
36
53
  map :ref, to: :ref
37
- map :multiplicity, to: :multiplicity
54
+ map :presence, to: :presence
55
+ map :count, to: :count
38
56
  map :is_delimiting, to: :is_delimiting
39
57
  end
40
58
 
41
59
  def validate!
42
60
  validate_ref!
43
- validate_multiplicity!
61
+ validate_presence_count!
44
62
  self
45
63
  end
46
64
 
47
- def compulsory?
48
- multiplicity == "compulsory"
65
+ def required?
66
+ presence == "required"
49
67
  end
50
68
 
51
69
  def optional?
52
- multiplicity == "optional"
70
+ presence == "optional"
53
71
  end
54
72
 
55
73
  def delimiting?
56
74
  is_delimiting == true
57
75
  end
58
76
 
77
+ # Derived ISO 704 name for display. Returns the flat-enum
78
+ # name that corresponds to this (presence, count) pair.
79
+ def iso704_name
80
+ case [presence, count]
81
+ when ["required", "exactly_one"] then "compulsory"
82
+ when ["optional", "exactly_one"] then "optional"
83
+ when ["required", "multiple"] then "compulsory_multiple"
84
+ when ["optional", "multiple"] then "optional_multiple"
85
+ when ["required", "at_least_one"] then "compulsory_at_least_one"
86
+ else raise ArgumentError,
87
+ "invalid combination presence=#{presence} count=#{count}"
88
+ end
89
+ end
90
+
59
91
  private
60
92
 
61
93
  def validate_ref!
@@ -66,15 +98,28 @@ module Glossarist
66
98
  "(source, id, or text required)"
67
99
  end
68
100
 
69
- def validate_multiplicity!
70
- return if multiplicity.nil?
101
+ def validate_presence_count!
102
+ unless Glossarist::GlossaryDefinition::PARTITIVE_PRESENCE_VALUES
103
+ .include?(presence)
104
+ raise ArgumentError,
105
+ "PartitiveMember#presence has invalid value " \
106
+ "#{presence.inspect}; must be one of " \
107
+ "#{GlossaryDefinition::PARTITIVE_PRESENCE_VALUES.join(', ')}"
108
+ end
109
+
110
+ unless Glossarist::GlossaryDefinition::PARTITIVE_COUNT_VALUES
111
+ .include?(count)
112
+ raise ArgumentError,
113
+ "PartitiveMember#count has invalid value " \
114
+ "#{count.inspect}; must be one of " \
115
+ "#{GlossaryDefinition::PARTITIVE_COUNT_VALUES.join(', ')}"
116
+ end
71
117
 
72
- unless Glossarist::GlossaryDefinition::MULTIPLICITY_VALUES
73
- .include?(multiplicity)
118
+ if presence == "optional" && count == "at_least_one"
74
119
  raise ArgumentError,
75
- "PartitiveMember#multiplicity has invalid value " \
76
- "#{multiplicity.inspect}; must be one of " \
77
- "#{GlossaryDefinition::MULTIPLICITY_VALUES.join(', ')}"
120
+ "PartitiveMember presence=optional + count=at_least_one is " \
121
+ "invalid it collapses to optional + multiple (zero or more). " \
122
+ "Use presence: optional, count: multiple instead."
78
123
  end
79
124
  end
80
125
  end
@@ -12,10 +12,9 @@ module Glossarist
12
12
  # within one relation are coordinate concepts: they share the
13
13
  # comprehensive AND share the criterion of subdivision.
14
14
  #
15
- # Per-partitive metadata (ISO 704:2022):
16
- # - multiplicity (compulsory, optional, compulsory_multiple,
17
- # optional_multiple, compulsory_at_least_one) — encodes the diagram
18
- # line notation as data
15
+ # Per-partitive metadata (ISO 704:2022, MECE decomposition):
16
+ # - presence (required, optional) — line style: solid vs dashed
17
+ # - count (exactly_one, at_least_one, multiple) — line count
19
18
  # - is_delimiting — orthogonal flag; a delimiting part behaves
20
19
  # like a delimiting characteristic (distinguishes the
21
20
  # comprehensive from coordinate concepts)
@@ -87,12 +87,12 @@ module Glossarist
87
87
 
88
88
  def check_member_multiplicity(rel, idx, fname, issues)
89
89
  rel.partitives.each_with_index do |member, mi|
90
- unless member.compulsory?
90
+ unless member.required? && member.count == "exactly_one"
91
91
  issues << issue(
92
92
  "partitive_relation #{idx + 1}.partitives[#{mi}] has " \
93
- "non-default multiplicity '#{member.multiplicity}'; " \
94
- "ISO 704 diagram uses dashed/multiple-line notation for " \
95
- "this — confirm the optionality is intentional",
93
+ "non-default presence='#{member.presence}' count='#{member.count}' " \
94
+ "(ISO 704 name: #{member.iso704_name}); confirm the " \
95
+ "optionality is intentional",
96
96
  severity: "warning",
97
97
  location: fname,
98
98
  )
@@ -4,5 +4,5 @@
4
4
  #
5
5
 
6
6
  module Glossarist
7
- VERSION = "2.13.3"
7
+ VERSION = "2.13.4"
8
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glossarist
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.13.3
4
+ version: 2.13.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-07-27 00:00:00.000000000 Z
11
+ date: 2026-07-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lutaml-model