linked-rolls 0.75.0 → 0.76.0

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.
@@ -97,57 +97,42 @@ const withChanges = (edition) => Array.isArray(edition.copies) ? { ...edition, c
97
97
  const silentTerms = new Set(Object.entries(context['@context'])
98
98
  .filter(([, definition]) => definition === null)
99
99
  .map(([term]) => term));
100
- const doubtedSetsOf = (edition) => new Map((edition.propositionSets ?? [])
101
- .filter(set => !isAsserted(set.belief.certainty))
102
- .map(set => [set.id, set.belief.id]));
103
- /** The set a value's annotation names instead of carrying a belief, where the edition doubts it. */
104
- const doubtedSetOf = (value, doubted) => {
105
- const annotation = value['@annotation'];
106
- return isRecord(annotation) && annotation.belief === undefined && typeof annotation['@id'] === 'string'
107
- ? doubted.get(annotation['@id']) && annotation['@id']
108
- : undefined;
109
- };
110
100
  /**
111
101
  * A reference its belief does not hold to be so: it names a node, states
112
- * nothing RDF would read besides, and its belief is below likely, or the
113
- * belief of the proposition set it belongs to is.
102
+ * nothing RDF would read besides, and its belief is below likely.
114
103
  */
115
- const isDoubtedReference = (value, doubted) => isRecord(value)
104
+ const isDoubtedReference = (value) => isRecord(value)
116
105
  && typeof value['@id'] === 'string'
117
106
  && isRecord(value['@annotation'])
118
- && (!isAsserted(certaintyOf(value)) || doubtedSetOf(value, doubted) !== undefined)
107
+ && !isAsserted(certaintyOf(value))
119
108
  && Object.keys(value).every(key => key === '@id' || key === '@annotation' || silentTerms.has(key));
120
109
  /**
121
110
  * The statement a doubted reference makes, as a JSON-LD-star embedded
122
111
  * node: the triple is named without being stated, and the belief is
123
112
  * about it. The annotation's own id goes along under a key RDF does not
124
- * read, so that an import can put it back. A statement that belongs to
125
- * a proposition set names the set's belief by its id, which is stated
126
- * with the set.
113
+ * read, so that an import can put it back.
127
114
  */
128
- const quote = (subject, key, reference, listed, doubted) => {
115
+ const quote = (subject, key, reference, listed) => {
129
116
  const { '@annotation': { '@id': annotation, ...about }, ...object } = reference;
130
- const set = doubtedSetOf(reference, doubted);
131
117
  return {
132
118
  '@id': { '@id': subject, [key]: listed ? [object] : object },
133
119
  annotation,
134
- ...about,
135
- ...(set !== undefined && { belief: { '@id': doubted.get(set) } })
120
+ ...about
136
121
  };
137
122
  };
138
123
  /** The value a node states under a key, less the doubted references, which go to the quoted. */
139
- const unquoted = (subject, key, value, quoted, doubted) => {
124
+ const unquoted = (subject, key, value, quoted) => {
140
125
  if (Array.isArray(value)) {
141
126
  return value.filter(item => {
142
- if (!isDoubtedReference(item, doubted))
127
+ if (!isDoubtedReference(item))
143
128
  return true;
144
- quoted.push(quote(subject, key, item, true, doubted));
129
+ quoted.push(quote(subject, key, item, true));
145
130
  return false;
146
131
  });
147
132
  }
148
- if (!isDoubtedReference(value, doubted))
133
+ if (!isDoubtedReference(value))
149
134
  return value;
150
- quoted.push(quote(subject, key, value, false, doubted));
135
+ quoted.push(quote(subject, key, value, false));
151
136
  return undefined;
152
137
  };
153
138
  /**
@@ -160,16 +145,16 @@ const unquoted = (subject, key, value, quoted, doubted) => {
160
145
  * between nodes are quoted, since only they can be put back where they
161
146
  * stood; a doubted date or attribution stays annotated in place.
162
147
  */
163
- const withDoubtedReferencesQuoted = (value, quoted, doubted) => {
148
+ const withDoubtedReferencesQuoted = (value, quoted) => {
164
149
  if (Array.isArray(value))
165
- return value.map(item => withDoubtedReferencesQuoted(item, quoted, doubted));
150
+ return value.map(item => withDoubtedReferencesQuoted(item, quoted));
166
151
  if (!isRecord(value))
167
152
  return value;
168
153
  const subject = value['@id'];
169
154
  const node = {};
170
155
  Object.entries(value).forEach(([key, child]) => {
171
- const stated = typeof subject === 'string' && !key.startsWith('@') ? unquoted(subject, key, child, quoted, doubted) : child;
172
- const below = withDoubtedReferencesQuoted(stated, quoted, doubted);
156
+ const stated = typeof subject === 'string' && !key.startsWith('@') ? unquoted(subject, key, child, quoted) : child;
157
+ const below = withDoubtedReferencesQuoted(stated, quoted);
173
158
  if (below !== undefined)
174
159
  node[key] = below;
175
160
  });
@@ -186,16 +171,12 @@ const atOwnPlacesAll = (edition) => edition.copies.some(copy => copy.measurement
186
171
  * and every version carries the context of its own reproducing system.
187
172
  * A reference the edition holds possible, unlikely or false is quoted
188
173
  * rather than stated, so that a reader of the RDF does not take it for
189
- * a fact, and so is one that belongs to a proposition set held so. A
190
- * statement that belongs to a set names the set in its annotation,
191
- * which in RDF makes the set its reifier, and the set, stated once
192
- * beside the document, carries the belief. The edition given is not
193
- * changed.
174
+ * a fact. The edition given is not changed.
194
175
  * @category Reading and writing
195
176
  */
196
177
  export const asJsonLd = (edition) => {
197
178
  const quoted = [];
198
- const node = withDoubtedReferencesQuoted(withSystemContexts(withCreations(withChanges(asJsonLdEntity(atOwnPlacesAll(edition))))), quoted, doubtedSetsOf(edition));
179
+ const node = withDoubtedReferencesQuoted(withSystemContexts(withCreations(withChanges(asJsonLdEntity(atOwnPlacesAll(edition))))), quoted);
199
180
  // The context is the export's own; one carried in from an import must not override it.
200
181
  const { base, '@context': carried, ...rest } = node;
201
182
  return {
@@ -1,7 +1,9 @@
1
1
  import { derivedKeys } from "./asJsonLd.js";
2
- import { migrate, plainCopyId } from "./migrate.js";
2
+ import { migrate, plainCopyId, uncheckedMotivation } from "./migrate.js";
3
3
  import { isDateString } from "../shared/utils.js";
4
4
  import { putOnAxis } from "../collation/alignment.js";
5
+ import { editsOf } from "../model/Version.js";
6
+ import { motivationOfChanges, proposedMotivations } from "../filiation/edits.js";
5
7
  import schema from "../schema.json" with { type: 'json' };
6
8
  export const importDate = (str) => {
7
9
  const [y, m, d] = str.split('-').map(s => parseInt(s, 10));
@@ -84,14 +86,15 @@ const withoutEmptyCreations = (json) => Array.isArray(json.versions)
84
86
  /** A statement an export quoted rather than stated: an included node whose id is a triple. */
85
87
  const isQuotedStatement = (node) => node !== null && typeof node === 'object' && node['@id'] !== null && typeof node['@id'] === 'object';
86
88
  /**
87
- * A belief named by its id alone, as a quoted statement names the belief
88
- * of the proposition set it belongs to, which is stated with the set.
89
+ * A belief named by its id alone, as a quoted statement of a document
90
+ * written before 0.76 named the belief of the proposition set it
91
+ * belonged to, which was stated with the set (`migrate`).
89
92
  */
90
93
  const isNamedBelief = (belief) => belief !== null && typeof belief === 'object' && Object.keys(belief).every(key => key === '@id');
91
94
  /**
92
95
  * The reference a quoted statement made, annotated again with the belief
93
- * the export set beside it, or where it belongs to a proposition set,
94
- * naming the set again.
96
+ * the export set beside it, or where it belonged to a proposition set,
97
+ * naming the set again for `migrate` to resolve.
95
98
  */
96
99
  const referenceOf = (statement) => {
97
100
  const { '@id': { '@id': subject, ...made }, annotation, ...stated } = statement;
@@ -153,5 +156,29 @@ export const importJsonLd = (json) => {
153
156
  ? context.find((c) => c['@base'])?.['@base'] || ''
154
157
  : '';
155
158
  (edition.copies ?? []).forEach(putOnAxis);
156
- return edition;
159
+ return withKindsReadOffShapes(edition);
160
+ };
161
+ /**
162
+ * Gives an edit that a document written before 0.76 left unchecked the
163
+ * motivation its shape calls for, read in the edition as it stands: the
164
+ * generic musical one or the technical one (`migrate`). The
165
+ * shapes are read off a copy, since what reads an edition settles it
166
+ * for good, and the edition an import returns is the caller's to change.
167
+ */
168
+ const withKindsReadOffShapes = (edition) => {
169
+ if (!(edition.versions ?? []).some(version => editsOf(version).some(edit => edit.motivation === uncheckedMotivation)))
170
+ return edition;
171
+ const probe = structuredClone(edition);
172
+ const versions = edition.versions.map(version => {
173
+ if (!editsOf(version).some(edit => edit.motivation === uncheckedMotivation))
174
+ return version;
175
+ const motivations = proposedMotivations(probe, version.id);
176
+ return {
177
+ ...version,
178
+ edits: editsOf(version).map(edit => edit.motivation === uncheckedMotivation
179
+ ? { ...edit, motivation: motivationOfChanges(motivations, [...(edit.insert ?? []).map(symbol => symbol.id), ...(edit.delete ?? [])]) }
180
+ : edit)
181
+ };
182
+ });
183
+ return { ...edition, versions };
157
184
  };
@@ -13,6 +13,13 @@
13
13
  type Json = any;
14
14
  /** A copy's id without the `copy/` that documents of earlier releases put before it. */
15
15
  export declare const plainCopyId: (id: string) => string;
16
+ /**
17
+ * The motivation an edit of a version that derives from another is left
18
+ * with where only the edition can tell what kind of change it is: one
19
+ * that states neither a kind nor a reason, as a collation once left
20
+ * them. `importJsonLd` reads its kind off its shape (`proposedMotivations`).
21
+ */
22
+ export declare const uncheckedMotivation = "unchecked";
16
23
  /**
17
24
  * Brings the JSON of an edition written by an earlier release of the
18
25
  * format up to the current shape. A document that is current already
package/lib/io/migrate.js CHANGED
@@ -4,6 +4,7 @@ import { trackerBars } from "../systems/index.js";
4
4
  import { welteT100 } from "../systems/welteT100/bar.js";
5
5
  import { isDateString } from "../shared/utils.js";
6
6
  import { mapped, withValues } from "../ops/immutable.js";
7
+ import { musicalChange, technicalChange } from "../model/Edit.js";
7
8
  const retiredVersionTypes = new Set(['edition', 'unicum']);
8
9
  /**
9
10
  * The vocabulary the steps below were written against, as it stood in
@@ -76,7 +77,9 @@ const isTypedCorrectError = (edit) => edit !== null && typeof edit === 'object'
76
77
  * it. An edit typed so states it as its motivation instead, where it
77
78
  * gives none of its own, and the version states what the motivation
78
79
  * means; one that gives a motivation of its own keeps that one. Either
79
- * way it states no kind, its shape being left to be read again.
80
+ * way it states no kind, its shape being left to be read again. Once
81
+ * motivations are the edition's, a corrected error is a musical change
82
+ * (`withMotivationsOfTheEdition`).
80
83
  */
81
84
  const withCorrectedErrorsMotivated = (node) => {
82
85
  if (!Array.isArray(node.edits) || !node.edits.some(isTypedCorrectError))
@@ -706,6 +709,168 @@ const withReferenceCopy = (edition) => {
706
709
  : edition;
707
710
  };
708
711
  const editionSteps = [withoutFormatVersion, withoutTempoAdjustment, withoutEditionType, withSystems, withEditors, withDerivationTolerance, withReferenceCopy];
712
+ /**
713
+ * The motivation an edit of a version that derives from another is left
714
+ * with where only the edition can tell what kind of change it is: one
715
+ * that states neither a kind nor a reason, as a collation once left
716
+ * them. `importJsonLd` reads its kind off its shape (`proposedMotivations`).
717
+ */
718
+ export const uncheckedMotivation = 'unchecked';
719
+ /** The kinds of edit, as they were stated once, whose shape is a musical decision. */
720
+ const musicalEditTypes = new Set(['additional-accent', 'shift', 'shorten', 'prolong']);
721
+ /** The kinds of edit, as they were stated once, whose shape is a technical change. */
722
+ const technicalEditTypes = new Set(['recoding', 'remove-redundancy', 'add-redundancy']);
723
+ const isRecord = (value) => value !== null && typeof value === 'object' && !Array.isArray(value);
724
+ /** Whether the version derives from another, so that its edits are changes rather than its text. */
725
+ const derives = (version) => Array.isArray(version?.basedOn) ? version.basedOn.length > 0 : version?.basedOn !== undefined;
726
+ /**
727
+ * The motivation an edit states once motivations say what kind of
728
+ * change it is, from the kind it was given and the reason it gave.
729
+ */
730
+ const motivationOfEdit = (editType, motivation, derived) => {
731
+ // A corrected error put back a perforation in its place, and so made a musical change.
732
+ const stated = motivation === 'corrected-error' ? musicalChange : motivation;
733
+ if (!derived)
734
+ return stated === uncheckedMotivation || stated === musicalChange ? undefined : stated;
735
+ const technical = typeof editType === 'string' && technicalEditTypes.has(editType);
736
+ // A reason given for a technical change explained what the change or the procedure says already.
737
+ if (technical)
738
+ return technicalChange;
739
+ if (stated === undefined || stated === uncheckedMotivation) {
740
+ return typeof editType === 'string' && musicalEditTypes.has(editType) ? musicalChange : uncheckedMotivation;
741
+ }
742
+ return stated;
743
+ };
744
+ /** Whether the document still states what motivations and kinds of edit were before 0.76. */
745
+ const statesMotivationsPerVersion = (versions) => versions.some(version => Array.isArray(version?.motivations)
746
+ || (Array.isArray(version?.edits) && version.edits.some((edit) => isRecord(edit) && (Object.hasOwn(edit, 'editType') || edit.motivation === 'corrected-error'))));
747
+ /**
748
+ * Before 0.76 each version stated the motivations its edits named, and
749
+ * an edit stated its kind beside its reason. The motivations are the
750
+ * edition's now, once each, and the motivation alone says what kind of
751
+ * change an edit is (`kindOfChange`):
752
+ *
753
+ * - A motivation two versions stated under one id with different notes
754
+ * is kept under an id of its own for the second.
755
+ * - The unchecked motivation goes, and so does the declaration of a
756
+ * corrected error: it put a perforation back in its place, and so is
757
+ * a musical change whose reason is not given.
758
+ * - An edit of a version that derives from another, that gave no reason
759
+ * or only that it was unchecked, is a musical change whose reason is
760
+ * not given where its kind was an added accent, a shift, a shortening
761
+ * or a prolongation, and a technical change where it was a recoding or
762
+ * a redundancy removed or added. One that stated no kind is left
763
+ * unchecked, for an import to read its kind off its shape.
764
+ * - A reason given for a recoding or a redundancy goes, since a
765
+ * technical change needs none, and a motivation nothing names any
766
+ * longer goes with it. Every other reason stays, and makes the change
767
+ * a musical one.
768
+ * - The edits of a version that derives from none state its text and
769
+ * keep no motivation but a reason someone gave.
770
+ */
771
+ const withMotivationsOfTheEdition = (edition) => {
772
+ const versions = listAt(edition, 'versions');
773
+ if (!versions || !statesMotivationsPerVersion(versions))
774
+ return edition;
775
+ const notes = new Map((listAt(edition, 'motivations') ?? []).filter(isRecord).map(motivation => [motivation['@id'], motivation]));
776
+ const referencedBefore = new Set();
777
+ const migrated = versions.map((version, index) => {
778
+ if (!isRecord(version))
779
+ return version;
780
+ const renamed = new Map();
781
+ for (const motivation of Array.isArray(version.motivations) ? version.motivations.filter(isRecord) : []) {
782
+ const id = motivation['@id'];
783
+ if (typeof id !== 'string' || id === uncheckedMotivation || id === 'corrected-error')
784
+ continue;
785
+ const known = notes.get(id);
786
+ if (!known)
787
+ notes.set(id, motivation);
788
+ else if (known.note !== motivation.note) {
789
+ const own = `${id}-${index}`;
790
+ renamed.set(id, own);
791
+ notes.set(own, { ...motivation, '@id': own });
792
+ }
793
+ }
794
+ const derived = derives(version);
795
+ const { motivations: _declared, ...rest } = version;
796
+ if (!Array.isArray(version.edits))
797
+ return rest;
798
+ return {
799
+ ...rest,
800
+ edits: version.edits.map((edit) => {
801
+ if (!isRecord(edit))
802
+ return edit;
803
+ const { editType, motivation: given, ...stated } = edit;
804
+ const named = typeof given === 'string' ? renamed.get(given) ?? given : given;
805
+ if (typeof named === 'string')
806
+ referencedBefore.add(named);
807
+ const motivation = motivationOfEdit(editType, named, derived);
808
+ return motivation === undefined ? stated : { ...stated, motivation };
809
+ })
810
+ };
811
+ });
812
+ const referenced = new Set(migrated.flatMap((version) => (Array.isArray(version?.edits) ? version.edits : []).map((edit) => edit?.motivation).filter((id) => typeof id === 'string')));
813
+ const motivations = [...notes.values()].filter(motivation => referenced.has(motivation['@id']) || !referencedBefore.has(motivation['@id']));
814
+ const { motivations: _stated, ...rest } = edition;
815
+ return { ...rest, versions: migrated, ...(motivations.length > 0 && { motivations }) };
816
+ };
817
+ /**
818
+ * Before 0.76 an adopted proposal was recorded as a proposition set: each
819
+ * statement of it named the set in its annotation, and the set held them
820
+ * under one belief whose inference named the release that found them and
821
+ * the rules it followed. The edition states what a program concluded
822
+ * plainly now, and its creation names the rules among its principles and
823
+ * the release among its software. A statement of a set the edition held
824
+ * below likely keeps the doubt, under a belief of its own that is the
825
+ * set's.
826
+ */
827
+ const withoutPropositionSets = (edition) => {
828
+ const sets = listAt(edition, 'propositionSets');
829
+ if (!sets)
830
+ return edition;
831
+ const beliefOf = new Map(sets.filter(isRecord).map(set => [set['@id'], set.belief]));
832
+ const inferences = sets.filter(isRecord).flatMap(set => Array.isArray(set.belief?.reasons) ? set.belief.reasons : []);
833
+ const rules = inferences.flatMap(inference => Array.isArray(inference?.applies) ? inference.applies : []);
834
+ const programs = inferences.flatMap(inference => Array.isArray(inference?.software) ? inference.software : []);
835
+ let held = 0;
836
+ const unset = (value) => {
837
+ if (Array.isArray(value))
838
+ return mapped(value, unset);
839
+ if (!isRecord(value))
840
+ return value;
841
+ const annotation = value['@annotation'];
842
+ const set = isRecord(annotation) && typeof annotation['@id'] === 'string' ? beliefOf.get(annotation['@id']) : undefined;
843
+ if (!set || (isRecord(annotation.belief) && Object.keys(annotation.belief).some(key => key !== '@id')))
844
+ return withValues(value, unset);
845
+ const { '@annotation': _member, ...rest } = value;
846
+ if (set.certainty === 'true' || set.certainty === 'likely')
847
+ return withValues(rest, unset);
848
+ held += 1;
849
+ return withValues({
850
+ ...rest,
851
+ '@annotation': { '@id': `${annotation['@id']}/${held}`, belief: { ...set, '@id': `${set['@id']}/${held}` } }
852
+ }, unset);
853
+ };
854
+ const { propositionSets: _recorded, ...rest } = edition;
855
+ const unsetted = unset(rest);
856
+ const creation = isRecord(unsetted.creation) ? unsetted.creation : undefined;
857
+ if (!creation)
858
+ return unsetted;
859
+ const principles = [...new Set([...(Array.isArray(creation.principles) ? creation.principles : []), ...rules])];
860
+ const known = Array.isArray(creation.software) ? creation.software : [];
861
+ const software = [...known, ...programs.filter((program, index) => !known.some((other) => other?.name === program?.name && other?.version === program?.version)
862
+ && programs.findIndex(other => other?.name === program?.name && other?.version === program?.version) === index)];
863
+ return {
864
+ ...unsetted,
865
+ creation: {
866
+ ...creation,
867
+ ...(principles.length > 0 && { principles }),
868
+ ...(software.length > 0 && { software })
869
+ }
870
+ };
871
+ };
872
+ /** Steps that read the document as the node steps leave it, an old document's kinds of edit renamed. */
873
+ const finalSteps = [withoutPropositionSets, withMotivationsOfTheEdition];
709
874
  /**
710
875
  * Brings the JSON of an edition written by an earlier release of the
711
876
  * format up to the current shape. A document that is current already
@@ -714,4 +879,4 @@ const editionSteps = [withoutFormatVersion, withoutTempoAdjustment, withoutEditi
714
879
  * to look at an old document as JSON.
715
880
  * @category Reading and writing
716
881
  */
717
- export const migrate = (edition) => walk(editionSteps.reduce((result, step) => step(result), edition));
882
+ export const migrate = (edition) => finalSteps.reduce((result, step) => step(result), walk(editionSteps.reduce((result, step) => step(result), edition)));
@@ -107,7 +107,9 @@ export type Concept = (WithId & Partial<Named>) | (Named & Partial<WithId>);
107
107
  /**
108
108
  * Software that captured a copy or measured it: the transcriber that
109
109
  * read a recording into notes, the emulator that wrote a MIDI file, the
110
- * program that found the holes on a scan or aligned two copies.
110
+ * program that found the holes on a scan or aligned two copies. Or the
111
+ * software an edition was made with, such as the release of this
112
+ * library that found its stemma.
111
113
  * @see crmdig:D14 Software
112
114
  * @category Format types
113
115
  */
@@ -21,10 +21,8 @@ export type Certainty = typeof certainties[number];
21
21
  */
22
22
  export declare const isAsserted: (certainty: Certainty) => boolean;
23
23
  /**
24
- * The certainty a statement is held with for itself. One that carries
25
- * no belief is stated plainly, and so held true; one that belongs to a
26
- * proposition set is held with the set's belief, which `certaintyIn`
27
- * reads.
24
+ * The certainty a statement is held with. One that carries no belief is
25
+ * stated plainly, and so held true.
28
26
  * @category Assumptions and beliefs
29
27
  */
30
28
  export declare const certaintyOf: (assumption: Readonly<Assumption>) => Certainty;
@@ -93,24 +91,6 @@ export interface Inference extends Argumentation<'inference'> {
93
91
  * @see crminf:J3 applied
94
92
  */
95
93
  applies?: string[];
96
- /**
97
- * The programs that drew the conclusion, each with its version,
98
- * where a program drew it: a stemma `proposeStemma` found, which the
99
- * editor ran and holds. The actor is the one who ran it, since a
100
- * program holds no belief. Naming software makes the inference a
101
- * digital machine event in the sense of CRMdig, which can be run
102
- * again on what it used, and the note states what it was run with.
103
- * @see crmdig:L23 used software or firmware
104
- */
105
- software?: Software[];
106
- /**
107
- * When the conclusion was drawn. It is part of the reason and
108
- * carries no belief of its own, and it tells a run of a program
109
- * from the next, since a program may conclude otherwise once it, or
110
- * what it used, has changed.
111
- * @see crm:P4 has time-span
112
- */
113
- date?: TimeSpan;
114
94
  }
115
95
  /**
116
96
  * A belief adoption takes over someone else's belief without checking it:
@@ -224,76 +204,20 @@ export interface Assumption {
224
204
  * Uses the JSON-LD-star `@annotation` mechanism to attach
225
205
  * epistemic metadata (certainty and reasons) to any triple.
226
206
  *
227
- * An annotation that carries no belief names, by its `id`, the
228
- * proposition set the statement belongs to (`PropositionSet`): the
229
- * statement is held with the belief the set states, together with
230
- * the other statements that name it.
207
+ * A statement that carries none is stated plainly, and what a
208
+ * program concluded is stated so too: an edition asserts its stemma
209
+ * and its edits, as a printed edition does, and its creation names
210
+ * the principles and the release they were found by
211
+ * (`EditionCreation`). A belief is kept for what the editor doubts.
231
212
  */
232
213
  '@annotation'?: WithId & {
233
214
  /**
234
- * The belief held about the annotated statement, where it is
235
- * held for itself rather than as one of a proposition set.
215
+ * The belief held about the annotated statement.
236
216
  * @see crminf:J4i is subject of
237
217
  */
238
- belief?: Belief;
218
+ belief: Belief;
239
219
  };
240
220
  }
241
- /**
242
- * Statements held together under one belief, because one reasoning
243
- * concluded them together: the derivations and edits of a stemma, which
244
- * a search such as `proposeStemma` scores as a whole rather than one
245
- * derivation at a time, or the edits a proposal grouped the changes of
246
- * versions into. Each statement belongs to the set by naming it in its
247
- * annotation, which carries the set's id and no belief of its own, and
248
- * the belief is stated here, once, with the reasoning that concluded
249
- * it. Read as RDF, the set is the reifier of each statement that names
250
- * it, which RDF 1.2 lets reify several.
251
- *
252
- * A statement the editor takes out of the set by giving it a belief of
253
- * its own is the editor's, and its reasons can name the set's belief as
254
- * a premise, so that what the editor decided apart from the program
255
- * stays apart from it.
256
- * @see crminf:I4 Proposition Set
257
- * @category Format types
258
- */
259
- export interface PropositionSet extends WithId {
260
- type: 'propositionSet';
261
- /**
262
- * The belief the statements of the set are held with, and the
263
- * reasons for it.
264
- * @see crminf:J4i is subject of
265
- */
266
- belief: Belief;
267
- }
268
- /**
269
- * Whether the statement carries a belief of its own, rather than none
270
- * or the belief of the proposition set it belongs to.
271
- * @category Assumptions and beliefs
272
- */
273
- export declare const isHeldForItself: (assumption: Readonly<Assumption>) => boolean;
274
- /**
275
- * The id of the proposition set the statement belongs to, where its
276
- * annotation names one instead of carrying a belief.
277
- * @category Assumptions and beliefs
278
- */
279
- export declare const propositionSetOf: (assumption: Readonly<Assumption>) => string | undefined;
280
- /**
281
- * The belief the statement is held with in the edition: its own, or
282
- * that of the proposition set it belongs to.
283
- * @category Assumptions and beliefs
284
- */
285
- export declare const beliefIn: (edition: {
286
- propositionSets?: readonly PropositionSet[];
287
- }, assumption: Readonly<Assumption>) => Belief | undefined;
288
- /**
289
- * The certainty the statement is held with in the edition: that of its
290
- * own belief, or of the proposition set it belongs to. One that carries
291
- * neither is stated plainly, and so held true.
292
- * @category Assumptions and beliefs
293
- */
294
- export declare const certaintyIn: (edition: {
295
- propositionSets?: readonly PropositionSet[];
296
- }, assumption: Readonly<Assumption>) => Certainty;
297
221
  /**
298
222
  * A value assumption wraps a literal value, e.g. a string, a number, a date, with an optional annotation.
299
223
  * Used for properties where the value itself may be uncertain,
@@ -19,47 +19,11 @@ export const certainties = [
19
19
  */
20
20
  export const isAsserted = (certainty) => certainty === 'true' || certainty === 'likely';
21
21
  /**
22
- * The certainty a statement is held with for itself. One that carries
23
- * no belief is stated plainly, and so held true; one that belongs to a
24
- * proposition set is held with the set's belief, which `certaintyIn`
25
- * reads.
22
+ * The certainty a statement is held with. One that carries no belief is
23
+ * stated plainly, and so held true.
26
24
  * @category Assumptions and beliefs
27
25
  */
28
- export const certaintyOf = (assumption) => assumption['@annotation']?.belief?.certainty ?? 'true';
29
- /**
30
- * Whether the statement carries a belief of its own, rather than none
31
- * or the belief of the proposition set it belongs to.
32
- * @category Assumptions and beliefs
33
- */
34
- export const isHeldForItself = (assumption) => assumption['@annotation']?.belief !== undefined;
35
- /**
36
- * The id of the proposition set the statement belongs to, where its
37
- * annotation names one instead of carrying a belief.
38
- * @category Assumptions and beliefs
39
- */
40
- export const propositionSetOf = (assumption) => {
41
- const annotation = assumption['@annotation'];
42
- return annotation && annotation.belief === undefined ? annotation.id : undefined;
43
- };
44
- /**
45
- * The belief the statement is held with in the edition: its own, or
46
- * that of the proposition set it belongs to.
47
- * @category Assumptions and beliefs
48
- */
49
- export const beliefIn = (edition, assumption) => {
50
- const own = assumption['@annotation']?.belief;
51
- if (own)
52
- return own;
53
- const set = propositionSetOf(assumption);
54
- return set === undefined ? undefined : edition.propositionSets?.find(candidate => candidate.id === set)?.belief;
55
- };
56
- /**
57
- * The certainty the statement is held with in the edition: that of its
58
- * own belief, or of the proposition set it belongs to. One that carries
59
- * neither is stated plainly, and so held true.
60
- * @category Assumptions and beliefs
61
- */
62
- export const certaintyIn = (edition, assumption) => beliefIn(edition, assumption)?.certainty ?? 'true';
26
+ export const certaintyOf = (assumption) => assumption['@annotation']?.belief.certainty ?? 'true';
63
27
  /**
64
28
  * The value the assumption holds, without the belief about it.
65
29
  * @category Assumptions and beliefs