B: Fix oss synthesis ordering and order propagation
Some checks are pending
Backend CI / build (3.12) (push) Waiting to run

This commit is contained in:
Ivan 2024-09-01 15:14:24 +03:00
parent 02e8d24d2b
commit c5c6c42007
4 changed files with 44 additions and 24 deletions

View File

@ -129,7 +129,7 @@ class OperationSchema:
if schema is not None and has_children:
rsform = RSForm(schema)
self.after_create_cst(rsform, list(rsform.constituents()))
self.after_create_cst(rsform, list(rsform.constituents().order_by('order')))
self.save(update_fields=['time_update'])
def set_arguments(self, target: int, arguments: list[Operation]) -> None:
@ -219,17 +219,17 @@ class OperationSchema:
def execute_operation(self, operation: Operation) -> bool:
''' Execute target operation. '''
schemas: list[LibraryItem] = [arg.argument.result for arg in operation.getArguments()]
schemas: list[LibraryItem] = [arg.argument.result for arg in operation.getArguments().order_by('pk')]
if None in schemas:
return False
substitutions = operation.getSubstitutions()
receiver = self.create_input(operation)
receiver = self.create_input(self.cache.operation_by_id[operation.pk])
parents: dict = {}
children: dict = {}
for operand in schemas:
schema = RSForm(operand)
items = list(schema.constituents())
items = list(schema.constituents().order_by('order'))
new_items = receiver.insert_copy(items)
for (i, cst) in enumerate(new_items):
parents[cst.pk] = items[i]
@ -240,21 +240,23 @@ class OperationSchema:
original = children[sub.original.pk]
replacement = children[sub.substitution.pk]
translated_substitutions.append((original, replacement))
# TODO: add auto substitutes for diamond
receiver.substitute(translated_substitutions)
# TODO: remove duplicates from diamond
for cst in receiver.constituents():
for cst in receiver.constituents().order_by('order'):
parent = parents.get(cst.pk)
assert parent is not None
Inheritance.objects.create(
operation=operation,
operation_id=operation.pk,
child=cst,
parent=parent
)
receiver.restore_order()
receiver.reset_aliases()
if len(self.cache.graph.outputs[operation.pk]) > 0:
self.after_create_cst(receiver, list(receiver.constituents().order_by('order')))
self.save(update_fields=['time_update'])
return True
@ -331,7 +333,7 @@ class OperationSchema:
self._execute_inherit_cst(
target_operation=target.pk,
source=parent_schema,
items=list(parent_schema.constituents()),
items=list(parent_schema.constituents().order_by('order')),
mapping={}
)
@ -769,7 +771,7 @@ class OssCache:
def insert_argument(self, argument: Argument) -> None:
''' Insert new argument. '''
self.graph.add_edge(argument.operation_id, argument.argument_id)
self.graph.add_edge(argument.argument_id, argument.operation_id)
def insert_inheritance(self, inheritance: Inheritance) -> None:
''' Insert new inheritance. '''
@ -811,7 +813,7 @@ class OssCache:
def remove_argument(self, argument: Argument) -> None:
''' Remove argument from cache. '''
self.graph.remove_edge(argument.operation_id, argument.argument_id)
self.graph.remove_edge(argument.argument_id, argument.operation_id)
def remove_substitution(self, target: Substitution) -> None:
''' Remove substitution from cache. '''

View File

@ -58,4 +58,4 @@ class PropagationFacade:
return
schema = RSForm(item)
PropagationFacade.before_delete_cst(schema, list(schema.constituents()))
PropagationFacade.before_delete_cst(schema, list(schema.constituents().order_by('order')))

View File

@ -132,7 +132,7 @@ class TestChangeOperations(EndpointTester):
self.assertEqual(self.ks5.constituents().count(), 6)
self.assertEqual(self.ks4D1.definition_formal, r'X4 X1')
self.assertEqual(self.ks4D2.definition_formal, r'X1 DEL DEL DEL D1')
self.assertEqual(self.ks5D4.definition_formal, r'X1 DEL DEL DEL D1 D2 D3')
self.assertEqual(self.ks5D4.definition_formal, r'DEL DEL X3 DEL D1 D2 D3')
@decl_endpoint('/api/oss/{item}/set-input', method='patch')
def test_set_input_null(self):
@ -155,7 +155,7 @@ class TestChangeOperations(EndpointTester):
self.assertEqual(self.ks5.constituents().count(), 6)
self.assertEqual(self.ks4D1.definition_formal, r'X4 X1')
self.assertEqual(self.ks4D2.definition_formal, r'X1 DEL DEL DEL D1')
self.assertEqual(self.ks5D4.definition_formal, r'X1 DEL DEL DEL D1 D2 D3')
self.assertEqual(self.ks5D4.definition_formal, r'DEL DEL X3 DEL D1 D2 D3')
@decl_endpoint('/api/oss/{item}/set-input', method='patch')
def test_set_input_change_schema(self):
@ -190,7 +190,7 @@ class TestChangeOperations(EndpointTester):
self.assertEqual(ks4Dks6.definition_formal, r'X5 X6')
self.assertEqual(self.ks4D1.definition_formal, r'X4 X1')
self.assertEqual(self.ks4D2.definition_formal, r'X1 DEL DEL DEL D1')
self.assertEqual(self.ks5D4.definition_formal, r'X1 DEL DEL DEL D1 D2 D3')
self.assertEqual(self.ks5D4.definition_formal, r'DEL DEL X3 DEL D1 D2 D3')
@decl_endpoint('/api/library/{item}', method='delete')
def test_delete_schema(self):
@ -206,7 +206,7 @@ class TestChangeOperations(EndpointTester):
self.assertEqual(self.ks4.constituents().count(), 4)
self.assertEqual(self.ks5.constituents().count(), 7)
self.assertEqual(self.ks4D2.definition_formal, r'DEL X2 X3 S1 DEL')
self.assertEqual(self.ks5D4.definition_formal, r'X1 X2 X3 S1 D1 DEL D3')
self.assertEqual(self.ks5D4.definition_formal, r'X1 X2 X3 S1 DEL D2 D3')
@decl_endpoint('/api/oss/{item}/delete-operation', method='patch')
def test_delete_operation_and_constituents(self):
@ -227,7 +227,7 @@ class TestChangeOperations(EndpointTester):
self.assertEqual(self.ks4.constituents().count(), 4)
self.assertEqual(self.ks5.constituents().count(), 7)
self.assertEqual(self.ks4D2.definition_formal, r'DEL X2 X3 S1 DEL')
self.assertEqual(self.ks5D4.definition_formal, r'X1 X2 X3 S1 D1 DEL D3')
self.assertEqual(self.ks5D4.definition_formal, r'X1 X2 X3 S1 DEL D2 D3')
@decl_endpoint('/api/oss/{item}/delete-operation', method='patch')
def test_delete_operation_keep_constituents(self):
@ -282,7 +282,7 @@ class TestChangeOperations(EndpointTester):
self.assertEqual(self.ks4.constituents().count(), 5)
self.assertEqual(self.ks5.constituents().count(), 7)
self.assertEqual(self.ks4D2.definition_formal, r'X1 D1 X3 S1 D1')
self.assertEqual(self.ks5D4.definition_formal, r'X1 D2 X3 S1 D1 D2 D3')
self.assertEqual(self.ks5D4.definition_formal, r'D1 X2 X3 S1 D1 D2 D3')
@decl_endpoint('/api/oss/{item}/update-operation', method='patch')
def test_change_arguments(self):
@ -307,7 +307,7 @@ class TestChangeOperations(EndpointTester):
self.assertEqual(self.ks4.constituents().count(), 4)
self.assertEqual(self.ks5.constituents().count(), 6)
self.assertEqual(self.ks4D2.definition_formal, r'X1 DEL DEL DEL D1')
self.assertEqual(self.ks5D4.definition_formal, r'X1 DEL DEL DEL D1 D2 D3')
self.assertEqual(self.ks5D4.definition_formal, r'DEL DEL X3 DEL D1 D2 D3')
data['arguments'] = [self.operation1.pk, self.operation2.pk]
self.executeOK(data=data, item=self.owned_id)
@ -320,4 +320,22 @@ class TestChangeOperations(EndpointTester):
self.assertEqual(self.ks4.constituents().count(), 7)
self.assertEqual(self.ks5.constituents().count(), 9)
self.assertEqual(self.ks4D2.definition_formal, r'X1 DEL DEL DEL D1')
self.assertEqual(self.ks5D4.definition_formal, r'X1 DEL DEL DEL D1 D2 D3')
self.assertEqual(self.ks5D4.definition_formal, r'DEL DEL X3 DEL D1 D2 D3')
@decl_endpoint('/api/oss/{item}/execute-operation', method='post')
def test_execute_middle_operation(self):
self.client.delete(f'/api/library/{self.ks4.model.pk}')
self.operation4.refresh_from_db()
self.ks5.refresh_from_db()
self.assertEqual(self.operation4.result, None)
self.assertEqual(self.ks5.constituents().count(), 3)
data = {
'target': self.operation4.pk,
'positions': []
}
self.executeOK(data=data, item=self.owned_id)
self.operation4.refresh_from_db()
self.ks5.refresh_from_db()
self.assertNotEqual(self.operation4.result, None)
self.assertEqual(self.ks5.constituents().count(), 8)

View File

@ -135,7 +135,7 @@ class TestChangeSubstitutions(EndpointTester):
self.assertEqual(subs3_4.first().substitution, self.ks3X1)
self.assertEqual(self.ks4D1.definition_formal, r'S1 S1')
self.assertEqual(self.ks4D2.definition_formal, r'S1 X2 X3 S1 D1')
self.assertEqual(self.ks5D4.definition_formal, r'X1 X2 X3 X1 D1 D2 D3')
self.assertEqual(self.ks5D4.definition_formal, r'X1 X2 X3 X3 D1 D2 D3')
@decl_endpoint('/api/rsforms/{schema}/substitute', method='patch')
def test_substitute_substitution(self):
@ -157,7 +157,7 @@ class TestChangeSubstitutions(EndpointTester):
self.assertEqual(subs3_4.first().substitution, self.ks3X1)
self.assertEqual(self.ks4D1.definition_formal, r'X2 X1')
self.assertEqual(self.ks4D2.definition_formal, r'X1 X2 X3 X2 D1')
self.assertEqual(self.ks5D4.definition_formal, r'X1 X2 X3 X2 D1 D2 D3')
self.assertEqual(self.ks5D4.definition_formal, r'X1 X2 X3 X1 D1 D2 D3')
@decl_endpoint('/api/rsforms/{schema}/delete-multiple-cst', method='patch')
def test_delete_original(self):
@ -171,7 +171,7 @@ class TestChangeSubstitutions(EndpointTester):
self.assertEqual(subs3_4.count(), 1)
self.assertEqual(self.ks5.constituents().count(), 7)
self.assertEqual(self.ks4D2.definition_formal, r'X1 X2 X3 S1 DEL')
self.assertEqual(self.ks5D4.definition_formal, r'X1 X2 X3 S1 D1 DEL D3')
self.assertEqual(self.ks5D4.definition_formal, r'X1 X2 X3 S1 DEL D2 D3')
@decl_endpoint('/api/rsforms/{schema}/delete-multiple-cst', method='patch')
def test_delete_substitution(self):
@ -187,4 +187,4 @@ class TestChangeSubstitutions(EndpointTester):
self.assertEqual(self.ks5.constituents().count(), 7)
self.assertEqual(self.ks4D1.definition_formal, r'X4 X1')
self.assertEqual(self.ks4D2.definition_formal, r'X1 X2 DEL DEL D1')
self.assertEqual(self.ks5D4.definition_formal, r'X1 X2 DEL DEL D1 D2 D3')
self.assertEqual(self.ks5D4.definition_formal, r'X1 DEL X3 DEL D1 D2 D3')