using Rugrid.Sdaid.Notation.Documents;
namespace Rugrid.Sdaid.Epas.Nts.Backend.ModificationSelection
{
/// <summary>
/// Распознавание в наименовании ТС марки, модели и остатка наименования без марки.
/// Чистый алгоритм: не строит группы, не фильтрует справочник по нормам и не решает,
/// что делать с пустым результатом.
/// </summary>
public class DOC_ModificationNameRecognition : IApplicationServiceDocument, IHasStructuralLinks, IFolder<NtsBackendFolder>
{
public SdaidLink[] Links => new[]
{
Rel.Uses<Rugrid.Sdaid.Epas.Nts.Domain.DOC_Vehicle>(),
Rel.Uses<Rugrid.Sdaid.Epas.Nts.Domain.DOC_VehicleMark>(),
Rel.Uses<Rugrid.Sdaid.Epas.Nts.Domain.DOC_VehicleMarkAlias>(),
Rel.Uses<Rugrid.Sdaid.Epas.Nts.Domain.DOC_VehicleModel>(),
};
public static string _refName = "Распознавание марки и модели ТС";
public string Name => "Распознавание марки и модели ТС";
public string Description =>
@"Распознавание в наименовании ТС марки, модели и остатка наименования без марки — чистый алгоритм без построения групп и фильтрации справочника по нормам.";
public string Version => "0.1";
public string Status => "draft";
public string[] Comments => new string[0];
public static string Purpose = $"""
## Назначение
Алгоритм отвечает только за разбор строки наименования ТС
({SdaidAnchors.RefTo<Rugrid.Sdaid.Epas.Nts.Domain.DOC_Vehicle>()}, «Марка и модель
базы ТС»): какая марка и какая модель распознаны и какая часть строки осталась после
удаления марки.
Он **не** строит базовую группу, **не** фильтрует модификации по нормам и топливу и
**не** решает, что делать с пустым результатом — это ответственность вызывающих
процедур:
- автоподбор группы модификаций —
{SdaidAnchors.RefTo<Rugrid.Sdaid.Epas.Nts.Backend.ModificationSelection.DOC_ModificationGroupSelection>()};
- установка маски в окне подбора —
{SdaidAnchors.RefTo<Rugrid.Sdaid.Epas.Nts.Ui.DOC_ModificationSelectionModal>()};
- предложение марки и модели в карточке модификации —
{SdaidAnchors.RefTo<Rugrid.Sdaid.Epas.Nts.Ui.DOC_VehicleModificationCard>()}.
""";
public static string Normalization = $"""
## Нормализация сравнений
Все сравнения идут по нормализованному ключу: нижний регистр, `ё` → `е`,
транслитерация кириллицы в латиницу, удаление всех небуквенно-цифровых символов.
Токены — части строки после разделителей длиной от 2 символов.
""";
public static string Brand = $"""
## Распознавание марки
**`DetectBrand(name)`** — каноническая марка по мастер-списку марок (drom +
постановление + доменный список) с алиасами
({SdaidAnchors.RefTo<Rugrid.Sdaid.Epas.Nts.Domain.DOC_VehicleMarkAlias>()}). Ключи
проверяются от длинных к коротким; результат — первое совпадение:
- для любого ключа — равенство токену;
- цифровой ключ — только равенство токену, без префиксов и подстрок;
- ключ длиной ≥ 3 — токен начинается с ключа;
- ключ длиной ≥ 4 — ключ входит в нормализованное имя целиком.
Если совпадений нет — пустая строка.
**`DetectBrandIn(rows, name)`** — марка только из справочника вида ТС. Сначала
берётся `DetectBrand(name)`; результат принимается, если такая марка есть среди марок
строк `rows`. Если каноническая марка в группе не найдена, повторно ищется самая
длинная марка среди марок `rows` по тем же критериям совпадения. Итог всегда — марка
из справочника вида ТС, поэтому омонимы мастер-списка не подставляются: например,
«Genesis» в «HYUNDAI GENESIS», где в справочнике это модель Hyundai.
Мастер-список марок — справочник {SdaidAnchors.RefTo<Rugrid.Sdaid.Epas.Nts.Domain.DOC_VehicleMark>()}
(наименование), алиасы — связанные записи
{SdaidAnchors.RefTo<Rugrid.Sdaid.Epas.Nts.Domain.DOC_VehicleMarkAlias>()}: токен
сопоставляется либо с наименованием марки, либо с алиасом любой её связанной записи.
""";
public static string Model = $"""
## Распознавание модели
**`DetectModel(rows, name)`** — среди моделей строк `rows`
({SdaidAnchors.RefTo<Rugrid.Sdaid.Epas.Nts.Domain.DOC_VehicleModel>()}) выбирается
модель с самым длинным нормализованным наименованием (от 2 символов), которое целиком
входит в нормализованное имя ТС. Если ни одна не входит — пустая строка.
""";
public static string NameRemainder = $"""
## Остаток наименования ТС
**`BuildNameRemainder(name)`** — часть строки «Марка и модель базы ТС» после удаления
марки: строка разбивается на токены, из них удаляются токены, являющиеся ключами марок
мастер-списка, оставшиеся токены (от 2 символов) склеиваются через пробел.
Это не отдельное поле ТС и не «модификация»: остаток — рабочий текст для поиска.
Вызывающие используют его по-разному:
- автоподбор и маска — как подстроку для фильтра по полному наименованию модификации
(когда модель не распознана);
- карточка модификации — как предложение в поле «Модель».
Источник строки — «Марка и модель базы ТС». Использовать ли для спецтехники ещё и
«Модель спец. автомобиля» — открытый вопрос
{SdaidAnchors.RefTo<Rugrid.Sdaid.Epas.Nts.Epics.NtsFuelCalc.OQ_ModificationSelection>()}.
""";
}
}