glossarist 0.4.25 → 0.4.26
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.
- package/package.json +1 -1
- package/src/diff/diff-renderer.js +14 -3
- package/src/migration/partitive-relation-migrator.js +2 -1
- package/src/models/index.js +14 -0
- package/src/models/multiplicity.js +67 -17
- package/src/models/partitive-count.js +20 -0
- package/src/models/partitive-member.js +51 -72
- package/src/models/partitive-presence.js +18 -0
- package/src/rdf/gloss-partitive-member.js +40 -12
- package/src/rdf/index.d.ts +2 -0
- package/src/rdf/index.js +1 -1
- package/src/rdf/predicates.d.ts +4 -0
- package/src/rdf/predicates.js +2 -0
package/package.json
CHANGED
|
@@ -222,19 +222,30 @@ function relationLabel(r) {
|
|
|
222
222
|
// Aggregate multiplicity + delimiting stats across a concept's
|
|
223
223
|
// PartitiveRelations. Used by dataset-level summaries, not by the
|
|
224
224
|
// per-relation diff label.
|
|
225
|
+
//
|
|
226
|
+
// v4: presence and count are independent dimensions. Stats include
|
|
227
|
+
// byPresence and byCount breakdowns so tools can query each axis
|
|
228
|
+
// independently ("show me all optional parts" or "show me all
|
|
229
|
+
// multiple-count parts").
|
|
225
230
|
export function multiplicityStats(relations) {
|
|
226
231
|
const byMultiplicity = {};
|
|
232
|
+
const byPresence = {};
|
|
233
|
+
const byCount = {};
|
|
227
234
|
let delimitingCount = 0;
|
|
228
235
|
let total = 0;
|
|
229
236
|
for (const rel of relations ?? []) {
|
|
230
237
|
for (const m of rel?.partitives ?? []) {
|
|
231
238
|
total += 1;
|
|
232
|
-
const
|
|
233
|
-
byMultiplicity[
|
|
239
|
+
const mult = m?.multiplicity ?? 'compulsory';
|
|
240
|
+
byMultiplicity[mult] = (byMultiplicity[mult] ?? 0) + 1;
|
|
241
|
+
const p = m?.presence ?? 'required';
|
|
242
|
+
const c = m?.count ?? 'exactly_one';
|
|
243
|
+
byPresence[p] = (byPresence[p] ?? 0) + 1;
|
|
244
|
+
byCount[c] = (byCount[c] ?? 0) + 1;
|
|
234
245
|
if (m?.is_delimiting === true) delimitingCount += 1;
|
|
235
246
|
}
|
|
236
247
|
}
|
|
237
|
-
return { total, byMultiplicity, delimiting: delimitingCount };
|
|
248
|
+
return { total, byMultiplicity, byPresence, byCount, delimiting: delimitingCount };
|
|
238
249
|
}
|
|
239
250
|
|
|
240
251
|
function itemLabel(item) {
|
|
@@ -54,7 +54,8 @@ export function migrateHyperedgeToRelation(v1Hash) {
|
|
|
54
54
|
const parts = Array.isArray(v1Hash.parts) ? v1Hash.parts : [];
|
|
55
55
|
out.partitives = parts.map(ref => ({
|
|
56
56
|
ref: { ...ref },
|
|
57
|
-
|
|
57
|
+
presence: 'required',
|
|
58
|
+
count: 'exactly_one',
|
|
58
59
|
}));
|
|
59
60
|
|
|
60
61
|
out.completeness = _migrateEnumeration(v1Hash.enumeration);
|
package/src/models/index.js
CHANGED
|
@@ -38,6 +38,18 @@ export {
|
|
|
38
38
|
// backward-compat input. New code should use v2 exclusively.
|
|
39
39
|
export { PartitiveRelation } from './partitive-relation.js';
|
|
40
40
|
export { PartitiveMember } from './partitive-member.js';
|
|
41
|
+
export {
|
|
42
|
+
PARTITIVE_PRESENCE,
|
|
43
|
+
PARTITIVE_PRESENCE_VALUES,
|
|
44
|
+
DEFAULT_PRESENCE,
|
|
45
|
+
isValidPresence,
|
|
46
|
+
} from './partitive-presence.js';
|
|
47
|
+
export {
|
|
48
|
+
PARTITIVE_COUNT,
|
|
49
|
+
PARTITIVE_COUNT_VALUES,
|
|
50
|
+
DEFAULT_COUNT,
|
|
51
|
+
isValidCount,
|
|
52
|
+
} from './partitive-count.js';
|
|
41
53
|
export {
|
|
42
54
|
COMPLETENESS,
|
|
43
55
|
COMPLETENESS_VALUES,
|
|
@@ -49,6 +61,8 @@ export {
|
|
|
49
61
|
MULTIPLICITY_VALUES,
|
|
50
62
|
DEFAULT_MULTIPLICITY,
|
|
51
63
|
isValidMultiplicity,
|
|
64
|
+
multiplicityFromPair,
|
|
65
|
+
pairFromMultiplicity,
|
|
52
66
|
} from './multiplicity.js';
|
|
53
67
|
|
|
54
68
|
// v1 → v2 migration helper. Pure function; idempotent.
|
|
@@ -1,24 +1,74 @@
|
|
|
1
|
-
// Multiplicity — ISO 704:2022 partitive
|
|
1
|
+
// Multiplicity — ISO 704:2022 partitive multiplicity (derived view).
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// compulsory_multiple — 2 solid lines (multiple must exist)
|
|
7
|
-
// optional_multiple — 2 dashed lines (multiple may exist)
|
|
8
|
-
// compulsory_at_least_one — 1 solid + 1 dashed line (at least one must exist)
|
|
3
|
+
// ISO 704:2022 multiplicity is the cross product of two orthogonal
|
|
4
|
+
// dimensions (PartitivePresence × PartitiveCount). The 5 valid
|
|
5
|
+
// combinations map to the 5 ISO 704 names:
|
|
9
6
|
//
|
|
10
|
-
//
|
|
7
|
+
// required × exactly_one → compulsory
|
|
8
|
+
// optional × exactly_one → optional
|
|
9
|
+
// required × multiple → compulsory_multiple
|
|
10
|
+
// optional × multiple → optional_multiple
|
|
11
|
+
// required × at_least_one → compulsory_at_least_one
|
|
12
|
+
//
|
|
13
|
+
// (optional × at_least_one is REDUNDANT with optional × multiple —
|
|
14
|
+
// "may exist, ≥1 if it does" = "may exist in any number" — and is
|
|
15
|
+
// explicitly rejected at construction with a clear error message.)
|
|
16
|
+
//
|
|
17
|
+
// This module is the SSOT for the (presence, count) → ISO name
|
|
18
|
+
// mapping. Both MULTIPLICITY constants and MULTIPLICITY_VALUES are
|
|
19
|
+
// derived from this single table; no duplicate string literals.
|
|
11
20
|
|
|
12
|
-
import {
|
|
21
|
+
import { PARTITIVE_PRESENCE } from './partitive-presence.js';
|
|
22
|
+
import { PARTITIVE_COUNT } from './partitive-count.js';
|
|
13
23
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
OPTIONAL:
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
24
|
+
const NAME_BY_PAIR = Object.freeze({
|
|
25
|
+
[`${PARTITIVE_PRESENCE.REQUIRED}:${PARTITIVE_COUNT.EXACTLY_ONE}`]: 'compulsory',
|
|
26
|
+
[`${PARTITIVE_PRESENCE.OPTIONAL}:${PARTITIVE_COUNT.EXACTLY_ONE}`]: 'optional',
|
|
27
|
+
[`${PARTITIVE_PRESENCE.REQUIRED}:${PARTITIVE_COUNT.MULTIPLE}`]: 'compulsory_multiple',
|
|
28
|
+
[`${PARTITIVE_PRESENCE.OPTIONAL}:${PARTITIVE_COUNT.MULTIPLE}`]: 'optional_multiple',
|
|
29
|
+
[`${PARTITIVE_PRESENCE.REQUIRED}:${PARTITIVE_COUNT.AT_LEAST_ONE}`]: 'compulsory_at_least_one',
|
|
20
30
|
});
|
|
21
31
|
|
|
22
|
-
|
|
32
|
+
const PAIR_BY_NAME = Object.freeze(
|
|
33
|
+
Object.fromEntries(
|
|
34
|
+
Object.entries(NAME_BY_PAIR).map(([pair, name]) => [name, pair]),
|
|
35
|
+
),
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
export const MULTIPLICITY = Object.freeze(
|
|
39
|
+
Object.fromEntries(
|
|
40
|
+
Object.values(NAME_BY_PAIR).map(name => [name.toUpperCase(), name]),
|
|
41
|
+
),
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
export const MULTIPLICITY_VALUES = Object.freeze(Object.values(NAME_BY_PAIR));
|
|
45
|
+
|
|
23
46
|
export const DEFAULT_MULTIPLICITY = MULTIPLICITY.COMPULSORY;
|
|
24
|
-
|
|
47
|
+
|
|
48
|
+
export function multiplicityFromPair(presence, count) {
|
|
49
|
+
const name = NAME_BY_PAIR[`${presence}:${count}`];
|
|
50
|
+
if (name == null) {
|
|
51
|
+
throw invalidCombinationError(presence, count);
|
|
52
|
+
}
|
|
53
|
+
return name;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function pairFromMultiplicity(name) {
|
|
57
|
+
const pair = PAIR_BY_NAME[name];
|
|
58
|
+
if (pair == null) {
|
|
59
|
+
throw new Error(`Unknown multiplicity: ${JSON.stringify(name)}`);
|
|
60
|
+
}
|
|
61
|
+
const [presence, count] = pair.split(':');
|
|
62
|
+
return { presence, count };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function isValidMultiplicity(name) {
|
|
66
|
+
return Object.prototype.hasOwnProperty.call(PAIR_BY_NAME, name);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function invalidCombinationError(presence, count) {
|
|
70
|
+
return new Error(
|
|
71
|
+
`Invalid multiplicity combination: presence=${presence}, count=${count}. ` +
|
|
72
|
+
`(optional + at_least_one collapses to optional + multiple — use count=multiple.)`,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// PartitiveCount — ISO 704:2022 partitive member count.
|
|
2
|
+
//
|
|
3
|
+
// count (line count):
|
|
4
|
+
// exactly_one — 1 line (exactly one instance)
|
|
5
|
+
// at_least_one — 1 solid + 1 dashed (at least one instance)
|
|
6
|
+
// multiple — 2 lines (multiple instances)
|
|
7
|
+
//
|
|
8
|
+
// Default: exactly_one.
|
|
9
|
+
|
|
10
|
+
import { makeEnum } from './enum.js';
|
|
11
|
+
|
|
12
|
+
export const PARTITIVE_COUNT = makeEnum('PARTITIVE_COUNT', {
|
|
13
|
+
EXACTLY_ONE: 'exactly_one',
|
|
14
|
+
AT_LEAST_ONE: 'at_least_one',
|
|
15
|
+
MULTIPLE: 'multiple',
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export const PARTITIVE_COUNT_VALUES = PARTITIVE_COUNT.VALUES;
|
|
19
|
+
export const DEFAULT_COUNT = PARTITIVE_COUNT.EXACTLY_ONE;
|
|
20
|
+
export const isValidCount = PARTITIVE_COUNT.isValid;
|
|
@@ -1,33 +1,35 @@
|
|
|
1
1
|
// PartitiveMember — one member of a PartitiveRelation.
|
|
2
2
|
//
|
|
3
3
|
// Carries a ConceptRef (the subordinate concept partitive) plus
|
|
4
|
-
// ISO 704:2022
|
|
4
|
+
// ISO 704:2022 presence + count + is_delimiting.
|
|
5
5
|
//
|
|
6
|
-
//
|
|
6
|
+
// Matches concept-model/models/concepts/PartitiveMember.lutaml exactly:
|
|
7
|
+
// +ref — ConceptRef [1]
|
|
8
|
+
// +presence — PartitivePresence [0..1] (default: required)
|
|
9
|
+
// +count — PartitiveCount [0..1] (default: exactly_one)
|
|
10
|
+
// +is_delimiting — Boolean [0..1] (default: false)
|
|
7
11
|
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
// compulsory_multiple — 2 solid lines (multiple must exist)
|
|
12
|
-
// optional_multiple — 2 dashed lines (multiple may exist)
|
|
13
|
-
// compulsory_at_least_one — 1 solid + 1 dashed (≥1 must exist)
|
|
12
|
+
// The combination (optional, at_least_one) is invalid: if a part is
|
|
13
|
+
// optional, the at-least-one constraint is vacuous and collapses to
|
|
14
|
+
// (optional, multiple). Rejected at construction.
|
|
14
15
|
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
// Whether a part is delimiting depends on the concept system, the
|
|
20
|
-
// coordinate concepts, the inheritance principle, and the criterion
|
|
21
|
-
// of subdivision used (ISO 704:2022 §5.5.4.2.1).
|
|
16
|
+
// ISO 704 "name" strings (compulsory, optional, etc.) are NOT part of
|
|
17
|
+
// the model — they're a display concern handled by multiplicityFromPair
|
|
18
|
+
// in the renderer/viewer layer. The model is purely presence + count.
|
|
22
19
|
|
|
23
20
|
import { GlossaristModel } from './base.js';
|
|
24
21
|
import { ConceptRef } from './concept-ref.js';
|
|
25
22
|
import {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
} from './
|
|
23
|
+
PARTITIVE_PRESENCE,
|
|
24
|
+
DEFAULT_PRESENCE,
|
|
25
|
+
PARTITIVE_PRESENCE_VALUES,
|
|
26
|
+
isValidPresence,
|
|
27
|
+
} from './partitive-presence.js';
|
|
28
|
+
import {
|
|
29
|
+
DEFAULT_COUNT,
|
|
30
|
+
PARTITIVE_COUNT_VALUES,
|
|
31
|
+
isValidCount,
|
|
32
|
+
} from './partitive-count.js';
|
|
31
33
|
|
|
32
34
|
export class PartitiveMember extends GlossaristModel {
|
|
33
35
|
constructor(data = {}) {
|
|
@@ -35,38 +37,17 @@ export class PartitiveMember extends GlossaristModel {
|
|
|
35
37
|
this.ref = data.ref instanceof ConceptRef
|
|
36
38
|
? data.ref
|
|
37
39
|
: new ConceptRef(data.ref ?? {});
|
|
38
|
-
this.
|
|
39
|
-
this.
|
|
40
|
+
this.presence = _resolvePresence(data.presence);
|
|
41
|
+
this.count = _resolveCount(data.count);
|
|
42
|
+
this.is_delimiting = data.is_delimiting === true;
|
|
40
43
|
|
|
41
44
|
_assertNonEmptyRef(this.ref);
|
|
45
|
+
_assertValidCombination(this.presence, this.count);
|
|
42
46
|
}
|
|
43
47
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
get isCompulsory() {
|
|
48
|
-
return this.multiplicity === MULTIPLICITY.COMPULSORY;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
get isOptional() {
|
|
52
|
-
return this.multiplicity === MULTIPLICITY.OPTIONAL;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
get isCompulsoryMultiple() {
|
|
56
|
-
return this.multiplicity === MULTIPLICITY.COMPULSORY_MULTIPLE;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
get isOptionalMultiple() {
|
|
60
|
-
return this.multiplicity === MULTIPLICITY.OPTIONAL_MULTIPLE;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
get isCompulsoryAtLeastOne() {
|
|
64
|
-
return this.multiplicity === MULTIPLICITY.COMPULSORY_AT_LEAST_ONE;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
get isDelimiting() {
|
|
68
|
-
return this.is_delimiting === true;
|
|
69
|
-
}
|
|
48
|
+
get isRequired() { return this.presence === PARTITIVE_PRESENCE.REQUIRED; }
|
|
49
|
+
get isOptional() { return this.presence === PARTITIVE_PRESENCE.OPTIONAL; }
|
|
50
|
+
get isDelimiting() { return this.is_delimiting === true; }
|
|
70
51
|
|
|
71
52
|
identity() {
|
|
72
53
|
return PartitiveMember.identityOf(this);
|
|
@@ -74,12 +55,9 @@ export class PartitiveMember extends GlossaristModel {
|
|
|
74
55
|
|
|
75
56
|
toJSON() {
|
|
76
57
|
const obj = { ref: this.ref.toJSON() };
|
|
77
|
-
if (this.
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
if (this.is_delimiting === true) {
|
|
81
|
-
obj.is_delimiting = true;
|
|
82
|
-
}
|
|
58
|
+
if (this.presence !== DEFAULT_PRESENCE) obj.presence = this.presence;
|
|
59
|
+
if (this.count !== DEFAULT_COUNT) obj.count = this.count;
|
|
60
|
+
if (this.is_delimiting === true) obj.is_delimiting = true;
|
|
83
61
|
return obj;
|
|
84
62
|
}
|
|
85
63
|
|
|
@@ -94,33 +72,34 @@ export class PartitiveMember extends GlossaristModel {
|
|
|
94
72
|
}
|
|
95
73
|
}
|
|
96
74
|
|
|
97
|
-
function
|
|
98
|
-
if (value == null) return
|
|
99
|
-
if (!
|
|
100
|
-
throw new Error(
|
|
101
|
-
`invalid multiplicity ${JSON.stringify(value)}; ` +
|
|
102
|
-
`must be one of ${MULTIPLICITY_VALUES.join(', ')}`,
|
|
103
|
-
);
|
|
75
|
+
function _resolvePresence(value) {
|
|
76
|
+
if (value == null) return DEFAULT_PRESENCE;
|
|
77
|
+
if (!isValidPresence(value)) {
|
|
78
|
+
throw new Error(`invalid presence ${JSON.stringify(value)}; must be one of ${PARTITIVE_PRESENCE_VALUES.join(', ')}`);
|
|
104
79
|
}
|
|
105
80
|
return value;
|
|
106
81
|
}
|
|
107
82
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
`PartitiveMember.${fieldName} must be a boolean; got ${typeof value} ` +
|
|
115
|
-
`${JSON.stringify(value)}`,
|
|
116
|
-
);
|
|
83
|
+
function _resolveCount(value) {
|
|
84
|
+
if (value == null) return DEFAULT_COUNT;
|
|
85
|
+
if (!isValidCount(value)) {
|
|
86
|
+
throw new Error(`invalid count ${JSON.stringify(value)}; must be one of ${PARTITIVE_COUNT_VALUES.join(', ')}`);
|
|
87
|
+
}
|
|
88
|
+
return value;
|
|
117
89
|
}
|
|
118
90
|
|
|
119
91
|
function _assertNonEmptyRef(ref) {
|
|
120
92
|
if (!ref.source && !ref.id && !ref.text) {
|
|
93
|
+
throw new Error('PartitiveMember#ref must be a non-empty ConceptRef (source, id, or text required)');
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function _assertValidCombination(presence, count) {
|
|
98
|
+
if (presence === 'optional' && count === 'at_least_one') {
|
|
121
99
|
throw new Error(
|
|
122
|
-
'PartitiveMember
|
|
123
|
-
'(
|
|
100
|
+
'PartitiveMember presence=optional + count=at_least_one is invalid — ' +
|
|
101
|
+
'it collapses to optional + multiple (zero or more). ' +
|
|
102
|
+
'Use presence: optional, count: multiple instead.',
|
|
124
103
|
);
|
|
125
104
|
}
|
|
126
105
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// PartitivePresence — ISO 704:2022 partitive member presence.
|
|
2
|
+
//
|
|
3
|
+
// presence (line style):
|
|
4
|
+
// required — solid line (must exist in every instance)
|
|
5
|
+
// optional — dashed line (may exist; exists in some instances)
|
|
6
|
+
//
|
|
7
|
+
// Default: required.
|
|
8
|
+
|
|
9
|
+
import { makeEnum } from './enum.js';
|
|
10
|
+
|
|
11
|
+
export const PARTITIVE_PRESENCE = makeEnum('PARTITIVE_PRESENCE', {
|
|
12
|
+
REQUIRED: 'required',
|
|
13
|
+
OPTIONAL: 'optional',
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
export const PARTITIVE_PRESENCE_VALUES = PARTITIVE_PRESENCE.VALUES;
|
|
17
|
+
export const DEFAULT_PRESENCE = PARTITIVE_PRESENCE.REQUIRED;
|
|
18
|
+
export const isValidPresence = PARTITIVE_PRESENCE.isValid;
|
|
@@ -1,32 +1,60 @@
|
|
|
1
1
|
// PartitiveMember → RDF quads.
|
|
2
2
|
//
|
|
3
|
-
// Emits per-member predicates (
|
|
4
|
-
// member's concept URI. The member URI
|
|
5
|
-
// (typically `gloss-partitive-relation.js`).
|
|
3
|
+
// Emits per-member predicates (presence, count, is_delimiting,
|
|
4
|
+
// derived multiplicity) onto the member's concept URI. The member URI
|
|
5
|
+
// is constructed by the caller (typically `gloss-partitive-relation.js`).
|
|
6
6
|
//
|
|
7
7
|
// Extracted from `gloss-partitive-relation.js` per
|
|
8
8
|
// TODO.partitive-relation-v3/04 so future emitters (a standalone
|
|
9
9
|
// PartitiveMember listing, a stats aggregator) can reuse this
|
|
10
10
|
// emission without modifying the relation emitter (OCP).
|
|
11
|
+
//
|
|
12
|
+
// v4 decomposition: ISO 704:2022 multiplicity is the cross product of
|
|
13
|
+
// two orthogonal dimensions (presence × count). Per the JSON-LD
|
|
14
|
+
// context (`"@type": "@id"`), all three are emitted as URI references
|
|
15
|
+
// into the corresponding SKOS taxonomy namespaces — none as literals.
|
|
16
|
+
//
|
|
17
|
+
// <member-uri> gloss:presence <.../presence/required|optional>
|
|
18
|
+
// <member-uri> gloss:count <.../count/exactly_one|at_least_one|multiple>
|
|
19
|
+
// <member-uri> gloss:multiplicity <.../multiplicity/{ISO name}> (derived, v3 compat)
|
|
20
|
+
// <member-uri> gloss:isDelimiting "true" (xsd:boolean)
|
|
11
21
|
|
|
12
22
|
import { PRED } from './predicates.js';
|
|
13
23
|
import { namedNode, literal, quad } from './terms.js';
|
|
14
24
|
|
|
15
|
-
// SKOS taxonomy
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
// MUST be URI references, not string literals. Emitted shape:
|
|
21
|
-
// <member-uri> gloss:multiplicity <.../multiplicity/compulsory>
|
|
25
|
+
// SKOS taxonomy namespaces (concept-model will ship these taxonomies).
|
|
26
|
+
// Until then, the URIs are forward-compatible and resolve once the
|
|
27
|
+
// taxonomies land.
|
|
28
|
+
export const PRESENCE_NS = 'https://www.glossarist.org/ontologies/presence/';
|
|
29
|
+
export const COUNT_NS = 'https://www.glossarist.org/ontologies/count/';
|
|
22
30
|
export const MULTIPLICITY_NS = 'https://www.glossarist.org/ontologies/multiplicity/';
|
|
23
31
|
|
|
24
32
|
export function* partitiveMemberToQuads(member, { memberUri }) {
|
|
25
|
-
if (member?.
|
|
33
|
+
if (member?.presence) {
|
|
34
|
+
yield quad(
|
|
35
|
+
namedNode(memberUri),
|
|
36
|
+
namedNode(PRED.gloss.presence),
|
|
37
|
+
namedNode(PRESENCE_NS + member.presence),
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
if (member?.count) {
|
|
41
|
+
yield quad(
|
|
42
|
+
namedNode(memberUri),
|
|
43
|
+
namedNode(PRED.gloss.count),
|
|
44
|
+
namedNode(COUNT_NS + member.count),
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
// Derived multiplicity URI for v3 RDF consumer backward compat.
|
|
48
|
+
// multiplicity is computed from (presence, count) via the model's
|
|
49
|
+
// accessor; fall back to the raw field for raw JSON input.
|
|
50
|
+
const mult = typeof member?.multiplicity === 'string'
|
|
51
|
+
? member.multiplicity
|
|
52
|
+
: null;
|
|
53
|
+
if (mult) {
|
|
26
54
|
yield quad(
|
|
27
55
|
namedNode(memberUri),
|
|
28
56
|
namedNode(PRED.gloss.multiplicity),
|
|
29
|
-
namedNode(MULTIPLICITY_NS +
|
|
57
|
+
namedNode(MULTIPLICITY_NS + mult),
|
|
30
58
|
);
|
|
31
59
|
}
|
|
32
60
|
if (member?.is_delimiting === true) {
|
package/src/rdf/index.d.ts
CHANGED
|
@@ -121,6 +121,8 @@ export interface PartitiveMemberEmitOptions {
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
export declare const MULTIPLICITY_NS: string;
|
|
124
|
+
export declare const PRESENCE_NS: string;
|
|
125
|
+
export declare const COUNT_NS: string;
|
|
124
126
|
|
|
125
127
|
export declare function partitiveMemberToQuads(
|
|
126
128
|
member: PartitiveMember,
|
package/src/rdf/index.js
CHANGED
|
@@ -27,7 +27,7 @@ export {
|
|
|
27
27
|
export { detailedDefinitionToQuads } from './gloss-detailed-definition.js';
|
|
28
28
|
export { conceptSourceToQuads } from './gloss-source.js';
|
|
29
29
|
export { hyperedgeToQuads, hyperedgeSubjectUri } from './gloss-hyperedge.js';
|
|
30
|
-
export { partitiveMemberToQuads, MULTIPLICITY_NS } from './gloss-partitive-member.js';
|
|
30
|
+
export { partitiveMemberToQuads, MULTIPLICITY_NS, PRESENCE_NS, COUNT_NS } from './gloss-partitive-member.js';
|
|
31
31
|
export { partitiveRelationToQuads, partitiveRelationSubjectUri } from './gloss-partitive-relation.js';
|
|
32
32
|
export {
|
|
33
33
|
nonVerbalRepToQuads,
|
package/src/rdf/predicates.d.ts
CHANGED
|
@@ -110,6 +110,8 @@ export declare const PRED = {
|
|
|
110
110
|
"hasPartitiveRelation": "https://www.glossarist.org/ontologies/hasPartitiveRelation",
|
|
111
111
|
"hasPartitive": "https://www.glossarist.org/ontologies/hasPartitive",
|
|
112
112
|
"completeness": "https://www.glossarist.org/ontologies/completeness",
|
|
113
|
+
"presence": "https://www.glossarist.org/ontologies/presence",
|
|
114
|
+
"count": "https://www.glossarist.org/ontologies/count",
|
|
113
115
|
"multiplicity": "https://www.glossarist.org/ontologies/multiplicity",
|
|
114
116
|
"isDelimiting": "https://www.glossarist.org/ontologies/isDelimiting",
|
|
115
117
|
"criterion": "https://www.glossarist.org/ontologies/criterion",
|
|
@@ -392,6 +394,8 @@ export type Predicate =
|
|
|
392
394
|
| "https://www.glossarist.org/ontologies/hasPartitiveRelation"
|
|
393
395
|
| "https://www.glossarist.org/ontologies/hasPartitive"
|
|
394
396
|
| "https://www.glossarist.org/ontologies/completeness"
|
|
397
|
+
| "https://www.glossarist.org/ontologies/presence"
|
|
398
|
+
| "https://www.glossarist.org/ontologies/count"
|
|
395
399
|
| "https://www.glossarist.org/ontologies/multiplicity"
|
|
396
400
|
| "https://www.glossarist.org/ontologies/isDelimiting"
|
|
397
401
|
| "https://www.glossarist.org/ontologies/criterion"
|
package/src/rdf/predicates.js
CHANGED
|
@@ -110,6 +110,8 @@ export const PRED = {
|
|
|
110
110
|
"hasPartitiveRelation": "https://www.glossarist.org/ontologies/hasPartitiveRelation",
|
|
111
111
|
"hasPartitive": "https://www.glossarist.org/ontologies/hasPartitive",
|
|
112
112
|
"completeness": "https://www.glossarist.org/ontologies/completeness",
|
|
113
|
+
"presence": "https://www.glossarist.org/ontologies/presence",
|
|
114
|
+
"count": "https://www.glossarist.org/ontologies/count",
|
|
113
115
|
"multiplicity": "https://www.glossarist.org/ontologies/multiplicity",
|
|
114
116
|
"isDelimiting": "https://www.glossarist.org/ontologies/isDelimiting",
|
|
115
117
|
"criterion": "https://www.glossarist.org/ontologies/criterion",
|