core/validators/ontology.validator.ts
core/validators/ontology.validator.ts is a file in GovLab Context. 174 lines of code and 19 definitions.
import type { CheckGaps, DeclaredCheck } from "#types/check.types";
import type { CrossFaceIssues, EmptyRequiredField, ResolutionIssues } from "#types/validation.types";
import { REF_COLLECTIONS, collectionRefResolver } from "#core/resolvers/reference.resolver";
import { aliasDefectsOf, aliasHoldersOf } from "#core/validators/alias.validator";
import {
ambiguousReasonRefsOf,
ungroundedGatesOf,
unresolvedGrammarGroundsOf,
} from "#core/validators/algorithm.reference.validator";
import { buildKindLookup, lexKindIssues, relationKindViolationsOf } from "#core/validators/kind.validator";
import {
crossFaceCollisions,
invalidSeveritiesOf,
unreachableAntiPatternsOf,
unresolvedExpressionsOf,
} from "#core/validators/architecture.validator";
import { deadSeedsOf, tensionIssuesOf } from "#core/validators/tension.validator";
import {
doctypeModelAxisOf,
ungroundedPagConstructsOf,
unresolvedPagGroundsOf,
} from "#core/validators/grammar.reference.validator";
import {
idShapedEdgeLabelsOf,
reasonDefectLines,
unresolvedLensDetectorsOf,
unresolvedReasonEdgesOf,
unresolvedShapeInstancesOf,
} from "#core/validators/reason.reference.validator";
import { invalidRecordDistinctsOf, undeclaredAdjacentPairsOf } from "#core/validators/record.validator";
import { repairDefectsOf, repairKindLookup } from "#core/validators/repair.validator";
import { unresolvedConceptRefsOf, variantIdsOf } from "#core/validators/concept.validator";
import { ALGO_SCHEMA } from "#configuration/schemas/algorithm.schema";
import { ARCH_SCHEMA } from "#configuration/schemas/architecture.schema";
import { COLLECTIONS } from "#configuration/constants/ontology.constants";
import type { Faces } from "#types/context.types";
import type { KindSchema } from "#types/field.types";
import { LEX_SCHEMA } from "#configuration/schemas/lexicon.schema";
import { ONTOLOGY_FACES } from "#core/registries/context.registry";
import type { UnreadKey } from "#types/record.types";
import { asciiArrowsOf } from "#core/validators/syntax.validator";
import { checkGapsOf } from "#core/analyzers/check.analyzer";
import { crossValidateFaces } from "#core/validators/vocabulary.validator";
import { emptyFields } from "#core/validators/field.validator";
import { exemplarGapsOf } from "#core/validators/exemplar.validator";
import { integrityIssuesOf } from "#core/validators/algorithm.validator";
import { reasonNativeIssuesOf } from "#core/validators/algorithm.reason.validator";
import { tagExampleDefectsOf } from "#core/validators/lexicon.validator";
type CheckParts =
| "checkDeclarationDefects"
| "secondCheckHomes"
| "uncheckedRecords"
| "uncoveredCollections"
| "unresolvedCheckRefs";
type CrossParts = "danglingPrincipleRefs" | "misspelledForces" | "unknownForces";
type ResolutionParts = Omit<ResolutionIssues, CheckParts | CrossParts | "integrity" | "reasonNative" | "total">;
const emptyFieldsOf = function emptyFieldsOf(
collection: string,
records: readonly { id: string }[],
schema: KindSchema,
): EmptyRequiredField[] {
return records.flatMap((record) =>
emptyFields(schema, record).map((field) => ({ collection, field, id: record.id })),
);
};
const unknownRecordKeysOf = function unknownRecordKeysOf(faces: Faces): UnreadKey[] {
return [
...faces.arch.unreadKeys(),
...faces.algo.unreadKeys(),
...faces.lex.unreadKeys(),
...faces.pag.unreadKeys(),
...faces.reason.unreadKeys(),
...faces.layerJoin.unreadKeys(),
];
};
const variantCollections = function variantCollections(faces: Faces): Map<string, readonly string[]> {
return new Map<string, readonly string[]>([
[COLLECTIONS.algorithms, faces.algo.all().map((contract) => contract.id)],
[COLLECTIONS.architecture, faces.arch.ids()],
...[...faces.reason.kindMembers()].map(([kind, ids]): [string, string[]] => [
`${COLLECTIONS.reasoning}:${kind}`,
[...ids],
]),
]);
};
const partsOf = function partsOf(faces: Faces): ResolutionParts {
const archIssues = faces.arch.validateOntology();
const algoIssues = faces.algo.validateOntology();
const lexKind = lexKindIssues(faces.lex, faces.arch);
return {
...faces.pag.validateOntology(),
aliasDefects: aliasDefectsOf(aliasHoldersOf(faces)),
ambiguousReasonRefs: ambiguousReasonRefsOf(faces),
asciiArrows: asciiArrowsOf(faces),
crossFaceIdCollisions: crossFaceCollisions(faces.arch, faces.lex),
deadResolutionSeeds: deadSeedsOf(faces.layerJoin),
doctypeModelAxis: doctypeModelAxisOf(faces),
duplicateIds: [...archIssues.duplicateIds, ...algoIssues.duplicateIds],
emptyRequiredFields: [
...emptyFieldsOf(COLLECTIONS.architecture, faces.arch.all(), ARCH_SCHEMA),
...emptyFieldsOf(COLLECTIONS.lexicon, faces.lex.all(), LEX_SCHEMA),
...emptyFieldsOf(COLLECTIONS.algorithms, faces.algo.all(), ALGO_SCHEMA),
],
exemplarGaps: exemplarGapsOf(faces.algo),
idShapedEdgeLabels: idShapedEdgeLabelsOf(faces),
invalidRecordDistincts: invalidRecordDistinctsOf(faces),
invalidSeverities: invalidSeveritiesOf(faces.arch),
kindConsistencyViolations: lexKind.kindConsistencyViolations,
lexDefects: lexKind.lexDefects,
reasonOntologyDefects: reasonDefectLines(faces.reason.validateReasonOntology()),
relationKindViolations: relationKindViolationsOf(faces.arch, buildKindLookup(faces)),
repairDefects: repairDefectsOf(faces.arch.all(), repairKindLookup(faces)),
tagExampleDefects: tagExampleDefectsOf(faces.lex),
undeclaredAdjacentPairs: undeclaredAdjacentPairsOf(faces),
ungroundedGates: ungroundedGatesOf(faces),
ungroundedPagConstructs: ungroundedPagConstructsOf(faces),
unknownRecordKeys: unknownRecordKeysOf(faces),
unreachableAntiPatterns: unreachableAntiPatternsOf(faces.arch),
unresolvedAlgoComposes: algoIssues.danglingComposes,
unresolvedArchEdges: archIssues.danglingEdges.filter((edge) => faces.lex.resolve(edge.target) === null),
unresolvedConceptRefs: unresolvedConceptRefsOf(collectionRefResolver(faces)),
unresolvedExpressions: unresolvedExpressionsOf(faces),
unresolvedGrammarGrounds: unresolvedGrammarGroundsOf(faces),
unresolvedLensDetectors: unresolvedLensDetectorsOf(faces),
unresolvedPagGrounds: unresolvedPagGroundsOf(faces),
unresolvedReasonEdges: unresolvedReasonEdgesOf(faces),
unresolvedShapeInstances: unresolvedShapeInstancesOf(faces),
unresolvedTensions: tensionIssuesOf(faces),
variantIds: variantIdsOf(variantCollections(faces)),
};
};
export const checkGapsFor = function checkGapsFor(faces: Faces, checks: readonly DeclaredCheck[] = []): CheckGaps {
return checkGapsOf(
faces,
{ collections: REF_COLLECTIONS, resolve: collectionRefResolver(faces) },
ONTOLOGY_FACES.map((face) => face.name),
checks,
);
};
const lengthSum = function lengthSum(lists: readonly (readonly unknown[])[]): number {
return lists.reduce((sum, list) => sum + list.length, 0);
};
export const runValidation = function runValidation(
faces: Faces,
checks: readonly DeclaredCheck[] = [],
): ResolutionIssues {
const parts = partsOf(faces);
const cross: CrossFaceIssues = crossValidateFaces(faces);
const reasonNative = reasonNativeIssuesOf(faces);
const integrity = integrityIssuesOf(faces);
const gaps = checkGapsFor(faces, checks);
const checkParts = {
checkDeclarationDefects: gaps.checkDeclarationDefects,
secondCheckHomes: gaps.secondCheckHomes,
uncheckedRecords: gaps.uncheckedRecords,
uncoveredCollections: gaps.uncoveredCollections,
unresolvedCheckRefs: gaps.unresolvedCheckRefs,
};
return {
...parts,
...checkParts,
danglingPrincipleRefs: cross.danglingPrincipleRefs,
integrity,
misspelledForces: cross.misspelledForces,
reasonNative,
total:
lengthSum(Object.values(parts)) +
lengthSum(Object.values(cross)) +
reasonNative.subtotal +
integrity.subtotal +
lengthSum(Object.values(checkParts)),
unknownForces: cross.unknownForces,
};
};