Chronaxis用户手册English
本页目录

chronaxis.planning.sequences

源码基线:8904c2f744951857659abd40aaa3535d57faf53c

1"""检查请求/响应点事件配对的公开声明,不读取信号或执行配对。23输入是JSON节点或冻结SequencePlan;输出为已验证的计划和联合依赖。4只引用同计划的点规则,拒绝活动、跨时钟、重名和非法延迟。观测条件直接5采用响应规则的条件,用户不需要重复配置另一份观测表达式。6"""78from dataclasses import dataclass9from .diagnostic_collection import usable_node, collect_node_error10from .checks import PlanValidationError11from .checks import array_at, duration_at, model_at, number_at, object_at, text_at12from .nodes import register_id13from ..core.validation import require_identifier14from ..core.types import TimeType15from ..timebase.conversion import require_int64_ns161718@dataclass(frozen=True)19class SequencePlan:20    """保存一个FIFO配对声明;延迟包含两端,max_pending限制同时等待的请求数。"""2122    sequence_id: str23    start_rule: str24    response_rule: str25    min_delay_ns: int26    max_delay_ns: int27    max_pending: int = 655362829    def __post_init__(self):30        """检查独立字段,不读取其他规则。3132        参数: 无。返回: None。异常: TypeError/ValueError为名称或整数边界错误。33        """34        for name in (self.sequence_id, self.start_rule, self.response_rule):35            require_identifier(name, 'sequence节点名称')36        if any(type(value) is not int for value in (self.min_delay_ns, self.max_delay_ns, self.max_pending)):37            raise TypeError('sequence延迟和容量须为原生整数')38        if not 0 <= self.min_delay_ns <= self.max_delay_ns or self.max_pending < 1:39            raise ValueError('sequence需要0<=min_delay<=max_delay及正max_pending')40        require_int64_ns(self.min_delay_ns, 'min_delay_ns')41        require_int64_ns(self.max_delay_ns, 'max_delay_ns')424344def sequence_dependencies(item, rules, bindings):45    """检查两端引用和时钟,返回两规则实际原信号依赖。4647    参数: item为SequencePlan,rules为RulePlan元组,bindings为声明或运行绑定。48    返回: 去重且稳定排序的别名tuple。异常: TypeError/ValueError为不支持的引用或时钟。49    """50    if type(item) is not SequencePlan:51        raise TypeError('sequences需要SequencePlan')52    catalog = {rule.rule_id: rule for rule in rules}53    dependencies = set()54    for name in (item.start_rule, item.response_rule):55        rule = catalog.get(name)56        if rule is None or rule.rule_type not in ('rising_edge', 'falling_edge', 'start_only'):57            raise ValueError('sequence只引用本计划rising/falling/start_only点规则:' + name)58        dependencies.update(rule.condition.dependencies)59    result = tuple(sorted(dependencies))60    bindings.require_synchronized(result)61    # 常量条件没有信号依赖,但使用dataset观测轴;其隐含时钟也必须与另一端相同。62    if any(not catalog[name].condition.dependencies for name in (item.start_rule, item.response_rule)):63        declared = getattr(bindings, 'declarations', bindings)64        evidenced = {proof.source for proof in declared.synchronization}65        sources = {source.name: source for source in declared.sources}66        for name in result:67            source = sources[bindings.resolve(name).source]68            mapped = (source.timebase == declared.timebase or source.name in evidenced69                or source.timebase.time_type is TimeType.ABSOLUTE and declared.timebase.time_type is TimeType.ABSOLUTE)70            if not mapped:71                raise ValueError('常量规则与响应/请求信号没有共同dataset时钟:' + source.name)72    return result737475def parse_sequences(value, rules, bindings, ids):76    """解析独立sequences数组,节点ID与规则/窗口/指标共用名称空间。7778    参数: value为JSON数组,rules/bindings为已验证声明,ids为本计划名称集合。79    返回: SequencePlan tuple。异常: PlanValidationError保留非法字段或引用的位置。80    """81    result = []82    for index, raw in enumerate(array_at(value, '$.sequences')):83        path = f'$.sequences[{index}]'84        if not usable_node(path, raw):85            continue86        try:87            path = f'$.sequences[{index}]'88            raw = object_at(raw, path, ('name', 'start', 'response', 'max_delay'), ('min_delay', 'max_pending'))89            item = model_at(SequencePlan, path, register_id(raw['name'], path + '.name', ids),90                text_at(raw['start'], path + '.start', identifier=True),91                text_at(raw['response'], path + '.response', identifier=True),92                duration_at(raw.get('min_delay', '0s'), path + '.min_delay'),93                duration_at(raw['max_delay'], path + '.max_delay'),94                number_at(raw.get('max_pending', 65536), path + '.max_pending', integer=True, minimum=1))95            model_at(sequence_dependencies, path, item, rules, bindings)96            result.append(item)97        except PlanValidationError as error:98            collect_node_error(error, path, raw)99    return tuple(result)100
Chronaxis 用户手册 · 离线阅读