2023-07-26 23:11:00 +03:00
|
|
|
|
import { TokenID } from './enums';
|
|
|
|
|
import { CstType, ExpressionStatus, type IConstituenta, type IRSForm, ParsingStatus, ValueClass } from './models';
|
2023-07-20 17:11:03 +03:00
|
|
|
|
|
|
|
|
|
export interface IRSButtonData {
|
|
|
|
|
text: string
|
|
|
|
|
tooltip: string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface IStatusInfo {
|
|
|
|
|
text: string
|
|
|
|
|
color: string
|
|
|
|
|
tooltip: string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getTypeLabel(cst: IConstituenta) {
|
|
|
|
|
if (cst.parse?.typification) {
|
2023-07-25 20:27:29 +03:00
|
|
|
|
return cst.parse.typification;
|
2023-07-20 17:11:03 +03:00
|
|
|
|
}
|
2023-07-25 20:27:29 +03:00
|
|
|
|
if (cst.parse?.status !== ParsingStatus.VERIFIED) {
|
|
|
|
|
return 'N/A';
|
2023-07-20 17:11:03 +03:00
|
|
|
|
}
|
|
|
|
|
return 'Логический';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getRSButtonData(id: TokenID): IRSButtonData {
|
2023-07-25 20:27:29 +03:00
|
|
|
|
switch (id) {
|
2023-07-20 17:11:03 +03:00
|
|
|
|
case TokenID.BOOLEAN: return {
|
2023-07-22 03:18:48 +03:00
|
|
|
|
text: 'ℬ()',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'Булеан [Alt + E]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.DECART: return {
|
|
|
|
|
text: '×',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'Декартово произведение [Shift + 8]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.PUNC_PL: return {
|
|
|
|
|
text: '( )',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'Скобки вокруг выражения [ Alt + Shift + 9 ]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.PUNC_SL: return {
|
|
|
|
|
text: '[ ]',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'Скобки вокруг выражения [ Alt + [ ]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.FORALL: return {
|
|
|
|
|
text: '∀',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'Квантор всеобщности [`]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.EXISTS: return {
|
|
|
|
|
text: '∃',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'Квантор существования [Shift + `]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.NOT: return {
|
|
|
|
|
text: '¬',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'Отрицание [Alt + `]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.AND: return {
|
|
|
|
|
text: '&',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'Конъюнкция [Alt + 3 ~ Shift + 7]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.OR: return {
|
|
|
|
|
text: '∨',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'дизъюнкция [Alt + Shift + 3]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.IMPLICATION: return {
|
|
|
|
|
text: '⇒',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'импликация [Alt + 4]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.EQUIVALENT: return {
|
|
|
|
|
text: '⇔',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'эквивалентность [Alt + Shift + 4]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.LIT_EMPTYSET: return {
|
|
|
|
|
text: '∅',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'пустое множество [Alt + X]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.LIT_INTSET: return {
|
|
|
|
|
text: 'Z',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'целые числа [Alt + Z]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.EQUAL: return {
|
|
|
|
|
text: '=',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'равенство'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.NOTEQUAL: return {
|
|
|
|
|
text: '≠',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'неравенство [Alt + Shift + `]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.GREATER_OR_EQ: return {
|
|
|
|
|
text: '≥',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'больше или равно'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.LESSER_OR_EQ: return {
|
|
|
|
|
text: '≤',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'меньше или равно'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.IN: return {
|
|
|
|
|
text: '∈',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'быть элементом (принадлежит) [Alt + \']'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.NOTIN: return {
|
|
|
|
|
text: '∉',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'не принадлежит [Alt + Shift + \']'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.SUBSET_OR_EQ: return {
|
|
|
|
|
text: '⊆',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'быть частью (нестрогое подмножество) [Alt + 2]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.SUBSET: return {
|
|
|
|
|
text: '⊂',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'строгое подмножество [Alt + ;]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.NOTSUBSET: return {
|
|
|
|
|
text: '⊄',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'не подмножество [Alt + Shift + 2]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.INTERSECTION: return {
|
|
|
|
|
text: '∩',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'пересечение [Alt + Y]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.UNION: return {
|
|
|
|
|
text: '∪',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'объединение [Alt + U]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
2023-07-22 03:18:48 +03:00
|
|
|
|
case TokenID.SET_MINUS: return {
|
2023-07-20 17:11:03 +03:00
|
|
|
|
text: '\\',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'Разность множеств [Alt + 5]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.SYMMINUS: return {
|
|
|
|
|
text: '∆',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'Симметрическая разность [Alt + Shift + 5]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.NT_DECLARATIVE_EXPR: return {
|
|
|
|
|
text: 'D{}',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'Декларативная форма определения терма [Alt + D]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.NT_IMPERATIVE_EXPR: return {
|
|
|
|
|
text: 'I{}',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'императивная форма определения терма [Alt + G]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.NT_RECURSIVE_FULL: return {
|
|
|
|
|
text: 'R{}',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'рекурсивная (цикличная) форма определения терма [Alt + T]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.BIGPR: return {
|
|
|
|
|
text: 'Pr1()',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'большая проекция [Alt + Q]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.SMALLPR: return {
|
|
|
|
|
text: 'pr1()',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'малая проекция [Alt + W]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.FILTER: return {
|
2023-07-22 03:18:48 +03:00
|
|
|
|
text: 'Fi1[]()',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'фильтр [Alt + F]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.REDUCE: return {
|
|
|
|
|
text: 'red()',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'множество-сумма [Alt + R]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.CARD: return {
|
|
|
|
|
text: 'card()',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'мощность [Alt + C]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.BOOL: return {
|
|
|
|
|
text: 'bool()',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'синглетон [Alt + B]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.DEBOOL: return {
|
|
|
|
|
text: 'debool()',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'десинглетон [Alt + V]'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.PUNC_ASSIGN: return {
|
|
|
|
|
text: ':=',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'присвоение (императивный синтаксис)'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
case TokenID.PUNC_ITERATE: return {
|
|
|
|
|
text: ':∈',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'перебор элементов множества (императивный синтаксис)'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
return {
|
|
|
|
|
text: 'undefined',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
tooltip: 'undefined'
|
2023-07-20 17:11:03 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getCstTypeLabel(type: CstType) {
|
2023-07-25 20:27:29 +03:00
|
|
|
|
switch (type) {
|
2023-07-20 17:11:03 +03:00
|
|
|
|
case CstType.BASE: return 'Базисное множество';
|
|
|
|
|
case CstType.CONSTANT: return 'Константное множество';
|
|
|
|
|
case CstType.STRUCTURED: return 'Родовая структура';
|
|
|
|
|
case CstType.AXIOM: return 'Аксиома';
|
|
|
|
|
case CstType.TERM: return 'Терм';
|
|
|
|
|
case CstType.FUNCTION: return 'Терм-функция';
|
|
|
|
|
case CstType.PREDICATE: return 'Предикат-функция';
|
|
|
|
|
case CstType.THEOREM: return 'Теорема';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-26 23:11:00 +03:00
|
|
|
|
export function getCstTypeShortcut(type: CstType) {
|
|
|
|
|
const prefix = getCstTypeLabel(type) + ' [Alt + ';
|
|
|
|
|
switch (type) {
|
|
|
|
|
case CstType.BASE: return prefix + '1]';
|
|
|
|
|
case CstType.STRUCTURED: return prefix + '2]';
|
|
|
|
|
case CstType.TERM: return prefix + '3]';
|
|
|
|
|
case CstType.AXIOM: return prefix + '4]';
|
|
|
|
|
case CstType.FUNCTION: return prefix + 'Q]';
|
|
|
|
|
case CstType.PREDICATE: return prefix + 'W]';
|
|
|
|
|
case CstType.CONSTANT: return prefix + '5]';
|
|
|
|
|
case CstType.THEOREM: return prefix + '6]';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-23 15:23:01 +03:00
|
|
|
|
export const CstTypeSelector = (Object.values(CstType)).map(
|
|
|
|
|
(typeStr) => {
|
|
|
|
|
const type = typeStr as CstType;
|
2023-07-25 20:27:29 +03:00
|
|
|
|
return { value: type, label: getCstTypeLabel(type) };
|
|
|
|
|
});
|
2023-07-23 15:23:01 +03:00
|
|
|
|
|
2023-07-20 17:11:03 +03:00
|
|
|
|
export function getCstTypePrefix(type: CstType) {
|
2023-07-25 20:27:29 +03:00
|
|
|
|
switch (type) {
|
2023-07-20 17:11:03 +03:00
|
|
|
|
case CstType.BASE: return 'X';
|
|
|
|
|
case CstType.CONSTANT: return 'C';
|
|
|
|
|
case CstType.STRUCTURED: return 'S';
|
|
|
|
|
case CstType.AXIOM: return 'A';
|
2023-07-25 00:20:37 +03:00
|
|
|
|
case CstType.TERM: return 'D';
|
2023-07-20 17:11:03 +03:00
|
|
|
|
case CstType.FUNCTION: return 'F';
|
|
|
|
|
case CstType.PREDICATE: return 'P';
|
|
|
|
|
case CstType.THEOREM: return 'T';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getStatusInfo(status?: ExpressionStatus): IStatusInfo {
|
|
|
|
|
switch (status) {
|
|
|
|
|
case ExpressionStatus.UNDEFINED: return {
|
|
|
|
|
text: 'N/A',
|
|
|
|
|
color: 'bg-[#b3bdff] dark:bg-[#1e00b3]',
|
|
|
|
|
tooltip: 'произошла ошибка при проверке выражения'
|
|
|
|
|
};
|
|
|
|
|
case ExpressionStatus.UNKNOWN: return {
|
|
|
|
|
text: 'неизв',
|
|
|
|
|
color: 'bg-[#b3bdff] dark:bg-[#1e00b3]',
|
|
|
|
|
tooltip: 'требует проверки выражения'
|
|
|
|
|
};
|
|
|
|
|
case ExpressionStatus.INCORRECT: return {
|
|
|
|
|
text: 'ошибка',
|
|
|
|
|
color: 'bg-[#ff8080] dark:bg-[#800000]',
|
|
|
|
|
tooltip: 'ошибка в выражении'
|
|
|
|
|
};
|
|
|
|
|
case ExpressionStatus.INCALCULABLE: return {
|
|
|
|
|
text: 'невыч',
|
|
|
|
|
color: 'bg-[#ffbb80] dark:bg-[#964600]',
|
|
|
|
|
tooltip: 'выражение не вычислимо (экспоненциальная сложность)'
|
|
|
|
|
};
|
|
|
|
|
case ExpressionStatus.PROPERTY: return {
|
|
|
|
|
text: 'св-во',
|
|
|
|
|
color: 'bg-[#a5e9fa] dark:bg-[#36899e]',
|
|
|
|
|
tooltip: 'можно проверить принадлежность, но нельзя получить значение'
|
|
|
|
|
};
|
|
|
|
|
case ExpressionStatus.VERIFIED: return {
|
|
|
|
|
text: 'ок',
|
|
|
|
|
color: 'bg-[#aaff80] dark:bg-[#2b8000]',
|
|
|
|
|
tooltip: 'выражение корректно и вычислимо'
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
return {
|
|
|
|
|
text: 'undefined',
|
|
|
|
|
color: '',
|
|
|
|
|
tooltip: '!ERROR!'
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-22 03:18:48 +03:00
|
|
|
|
export function extractGlobals(expression: string): Set<string> {
|
2023-07-25 20:27:29 +03:00
|
|
|
|
return new Set(expression.match(/[XCSADFPT]\d+/g) ?? []);
|
2023-07-23 15:23:01 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function createAliasFor(type: CstType, schema: IRSForm): string {
|
2023-07-25 20:27:29 +03:00
|
|
|
|
const prefix = getCstTypePrefix(type);
|
2023-07-25 00:20:37 +03:00
|
|
|
|
if (!schema.items || schema.items.length <= 0) {
|
|
|
|
|
return `${prefix}1`;
|
2023-07-23 15:23:01 +03:00
|
|
|
|
}
|
2023-07-25 00:20:37 +03:00
|
|
|
|
const index = schema.items.reduce((prev, cst, index) => {
|
|
|
|
|
if (cst.cstType !== type) {
|
|
|
|
|
return prev;
|
|
|
|
|
}
|
|
|
|
|
index = Number(cst.alias.slice(1 - cst.alias.length)) + 1;
|
|
|
|
|
return Math.max(prev, index);
|
|
|
|
|
}, 1);
|
|
|
|
|
return `${prefix}${index}`;
|
2023-07-25 20:27:29 +03:00
|
|
|
|
}
|
2023-07-26 23:11:00 +03:00
|
|
|
|
|
|
|
|
|
export function getMockConstituenta(id: number, alias: string, type: CstType, comment: string): IConstituenta {
|
|
|
|
|
return {
|
|
|
|
|
id: id,
|
|
|
|
|
alias: alias,
|
|
|
|
|
convention: comment,
|
|
|
|
|
cstType: type,
|
|
|
|
|
term: {
|
|
|
|
|
raw: '',
|
|
|
|
|
resolved: '',
|
|
|
|
|
forms: []
|
|
|
|
|
},
|
|
|
|
|
definition: {
|
|
|
|
|
formal: '',
|
|
|
|
|
text: {
|
|
|
|
|
raw: '',
|
|
|
|
|
resolved: ''
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
parse: {
|
|
|
|
|
status: ParsingStatus.INCORRECT,
|
|
|
|
|
valueClass: ValueClass.INVALID,
|
|
|
|
|
typification: 'N/A',
|
|
|
|
|
syntaxTree: ''
|
|
|
|
|
}
|
|
|
|
|
};
|
2023-07-28 01:37:26 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getCloneTitle(schema: IRSForm): string {
|
|
|
|
|
if (!schema.title.includes('[клон]')) {
|
|
|
|
|
return schema.title + ' [клон]';
|
|
|
|
|
} else {
|
|
|
|
|
return (schema.title + '+');
|
|
|
|
|
}
|
2023-07-26 23:11:00 +03:00
|
|
|
|
}
|