123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- from enum import *
- from dataclasses import *
- from typing import *
- import itertools
- from sccd.statechart.static.tree import *
- from sccd.action_lang.static.scope import *
- class SemanticAspect:
- def __str__(self):
- # Override default: only print field, not the type (e.g. "TAKE_ONE" instead of "BigStepMaximality.TAKE_ONE")
- return self.name
- class BigStepMaximality(SemanticAspect, Enum):
- TAKE_ONE = auto()
- TAKE_MANY = auto()
- SYNTACTIC = auto()
- class ComboStepMaximality(SemanticAspect, Enum):
- COMBO_TAKE_ONE = auto()
- COMBO_TAKE_MANY = auto()
- class InternalEventLifeline(SemanticAspect, Enum):
- QUEUE = auto()
- NEXT_COMBO_STEP = auto()
- NEXT_SMALL_STEP = auto()
- REMAINDER = auto()
- SAME = auto()
- class InputEventLifeline(SemanticAspect, Enum):
- WHOLE = auto()
- FIRST_COMBO_STEP = auto()
- FIRST_SMALL_STEP = auto()
- class MemoryProtocol(SemanticAspect, Enum):
- BIG_STEP = auto()
- COMBO_STEP = auto()
- SMALL_STEP = auto()
- # NONE = auto()
- class Priority(SemanticAspect, Enum):
- SOURCE_PARENT = auto()
- SOURCE_CHILD = auto()
- ARENA_PARENT = auto()
- ARENA_CHILD = auto()
- class Concurrency(SemanticAspect, Enum):
- SINGLE = auto()
- MANY = auto()
- _T = TypeVar('_T', bound=SemanticAspect)
- SemanticChoice = Union[_T, List[_T]]
- @dataclass
- class SemanticConfiguration:
- # All semantic aspects and their default values.
- # Every field can be set to a list of multiple options, or just a value.
- # The following is the default configuration:
- big_step_maximality: SemanticChoice[BigStepMaximality] = BigStepMaximality.TAKE_MANY
- combo_step_maximality: SemanticChoice[ComboStepMaximality] = ComboStepMaximality.COMBO_TAKE_ONE
- internal_event_lifeline: SemanticChoice[InternalEventLifeline] = InternalEventLifeline.NEXT_COMBO_STEP
- input_event_lifeline: SemanticChoice[InputEventLifeline] = InputEventLifeline.FIRST_COMBO_STEP
- enabledness_memory_protocol: SemanticChoice[MemoryProtocol] = MemoryProtocol.COMBO_STEP
- assignment_memory_protocol: SemanticChoice[MemoryProtocol] = MemoryProtocol.COMBO_STEP
- priority: SemanticChoice[Priority] = Priority.SOURCE_PARENT
- concurrency: SemanticChoice[Concurrency] = Concurrency.SINGLE
- def __str__(self):
- s = ""
- for f in fields(self):
- s += "\n %s: %s" % (f.name, getattr(self, f.name))
- return s
- @classmethod
- def get_fields(cls) -> Iterator[Tuple[str, SemanticAspect]]:
- return ((f.name, type(f.default)) for f in fields(cls))
- # Whether multiple options are set for any aspect.
- def has_multiple_variants(self) -> bool:
- for f in fields(self):
- if isinstance(getattr(self, f.name), list):
- return True
- return False
- # Get all possible combinations for aspects with multiple options (as a list) set.
- # Calling has_multiple_variants on resulting objects will return False.
- def generate_variants(self) -> List['SemanticConfiguration']:
- my_fields = fields(self)
- chosen_options = ([item] if not isinstance(item,list) else item for item in (getattr(self, f.name) for f in my_fields))
- variants = itertools.product(*chosen_options)
- return [SemanticConfiguration(**{f.name: o for f,o in zip(my_fields, variant)}) for variant in variants]
- @dataclass
- class Statechart(Freezable):
- __slots__ = ["semantics", "scope", "datamodel", "internal_events", "internally_raised_events", "inport_events", "event_outport", "tree"]
- def __init__(self, semantics: SemanticConfiguration, scope: Scope, datamodel: Optional[Block], internal_events: Bitmap, internally_raised_events: Bitmap, inport_events: Dict[str, Set[int]], event_outport: Dict[str, str], tree: StateTree):
-
- super().__init__()
-
- # Semantic configuration for statechart execution
- self.semantics: SemanticConfiguration = semantics
- # Instance scope, the set of variable names (and their types and offsets in memory) that belong to the statechart
- self.scope: Scope = scope
- # Block of statements setting up the datamodel (variables in instance scope)
- self.datamodel: Optional[Block] = datamodel
- # Union of internally raised and input events. Basically all the events that a transition could be triggered by.
- self.internal_events: Bitmap = internal_events
- # All internally raised events in the statechart, may overlap with input events, as an event can be both an input event and internally raised.
- self.internally_raised_events: Bitmap = internally_raised_events
- # Mapping from inport to set of event IDs - currently unused
- self.inport_events: Dict[str, Bitmap] = inport_events
- # Mapping from event name to outport
- self.event_outport: Dict[str, str] = event_outport
- self.tree: StateTree = tree
|