mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 21:10:38 +03:00
121 lines
3.9 KiB
Python
121 lines
3.9 KiB
Python
''' Models: Definitions and utility function for RSLanguage. '''
|
|
import json
|
|
from typing import Tuple
|
|
from enum import IntEnum , unique
|
|
|
|
from django.db.models import TextChoices
|
|
|
|
import pyconcept
|
|
|
|
from .. import messages as msg
|
|
|
|
|
|
@unique
|
|
class TokenType(IntEnum):
|
|
''' Some of grammar token types. Full list seek in frontend / pyconcept '''
|
|
ID_GLOBAL = 259
|
|
ID_RADICAL = 262
|
|
DECART = 287
|
|
BOOLEAN = 292
|
|
BIGPR = 293
|
|
SMALLPR = 294
|
|
REDUCE = 299
|
|
|
|
|
|
class CstType(TextChoices):
|
|
''' Type of constituenta '''
|
|
BASE = 'basic'
|
|
CONSTANT = 'constant'
|
|
STRUCTURED = 'structure'
|
|
AXIOM = 'axiom'
|
|
TERM = 'term'
|
|
FUNCTION = 'function'
|
|
PREDICATE = 'predicate'
|
|
THEOREM = 'theorem'
|
|
|
|
|
|
def get_type_prefix(cst_type: CstType) -> str:
|
|
''' Get alias prefix. '''
|
|
if cst_type == CstType.BASE:
|
|
return 'X'
|
|
if cst_type == CstType.CONSTANT:
|
|
return 'C'
|
|
if cst_type == CstType.STRUCTURED:
|
|
return 'S'
|
|
if cst_type == CstType.AXIOM:
|
|
return 'A'
|
|
if cst_type == CstType.TERM:
|
|
return 'D'
|
|
if cst_type == CstType.FUNCTION:
|
|
return 'F'
|
|
if cst_type == CstType.PREDICATE:
|
|
return 'P'
|
|
if cst_type == CstType.THEOREM:
|
|
return 'T'
|
|
return 'X'
|
|
|
|
def _get_structure_prefix(alias: str, expression: str, parse: dict) -> Tuple[str, str]:
|
|
''' Generate prefix and alias for structure generation. '''
|
|
args = parse['args']
|
|
if len(args) == 0:
|
|
return (alias, '')
|
|
prefix = expression[0:expression.find(']')] + '] '
|
|
newAlias = alias + '[' + ','.join([arg['alias'] for arg in args]) + ']'
|
|
return (newAlias, prefix)
|
|
|
|
def generate_structure(alias: str, expression: str, parse: dict) -> list:
|
|
''' Generate list of expressions for target structure. '''
|
|
ast = json.loads(pyconcept.parse_expression(parse['typification']))['ast']
|
|
if len(ast) == 0:
|
|
raise ValueError(msg.typificationInvalidStr())
|
|
if len(ast) == 1:
|
|
return []
|
|
(link, prefix) = _get_structure_prefix(alias, expression, parse)
|
|
|
|
generated: list = []
|
|
arity: list = [1] * len(ast)
|
|
for (n, item) in enumerate(ast):
|
|
if n == 0:
|
|
generated.append({
|
|
'text': link, # generated text
|
|
'operation': None, # applied operation. None if text should be skipped
|
|
'is_boolean': False # is the result of operation has an additional boolean
|
|
})
|
|
continue
|
|
|
|
parent_index = item['parent']
|
|
parent_type = ast[parent_index]['typeID']
|
|
parent_text = generated[parent_index]['text']
|
|
parent_is_boolean = generated[parent_index]['is_boolean']
|
|
assert(parent_type in [TokenType.BOOLEAN, TokenType.DECART])
|
|
|
|
if parent_is_boolean:
|
|
if parent_type == TokenType.BOOLEAN:
|
|
generated.append({
|
|
'text': f'red({parent_text})',
|
|
'operation': TokenType.REDUCE,
|
|
'is_boolean': True
|
|
})
|
|
if parent_type == TokenType.DECART:
|
|
generated.append({
|
|
'text': f'Pr{arity[parent_index]}({parent_text})',
|
|
'operation': TokenType.BIGPR,
|
|
'is_boolean': True
|
|
})
|
|
arity[parent_index] = arity[parent_index] + 1
|
|
else:
|
|
if parent_type == TokenType.BOOLEAN:
|
|
generated.append({
|
|
'text': parent_text,
|
|
'operation': None,
|
|
'is_boolean': True
|
|
})
|
|
if parent_type == TokenType.DECART:
|
|
generated.append({
|
|
'text': f'pr{arity[parent_index]}({parent_text})',
|
|
'operation': TokenType.SMALLPR,
|
|
'is_boolean': False
|
|
})
|
|
arity[parent_index] = arity[parent_index] + 1
|
|
return [prefix + item['text'] for item in generated if item['operation'] is not None]
|