Chronaxis用户手册English
本页目录

chronaxis.core.condition_evidence

源码基线:8904c2f744951857659abd40aaa3535d57faf53c

1"""把同轴的更新前点、连续后态及当前点求值结果组装成条件证据。23输入为调用方已经求出的三个BOOL视图、整数纳秒轴,以及实际更新、真实无效更新、4来源结束和会话terminal四种独立标志;输出冻结ConditionTick tuple。更新前点只用于5证明真实更新是否导致UNKNOWN,不把其反事实诊断加入当前真实诊断。terminal强制6连续状态UNKNOWN并叠加MISSING,当前点仍可保留真正末点的TRUE或FALSE。7参考实现逐点使用标量结果,数组实现独立执行valid/quality与因果掩码运算,最后装箱。8本模块不求值表达式、不读取来源、不访问state或时钟、不生成时间轴,也不更新检测器。9数组临时列及输出规模随N增长,后续调用方必须先申请预算;本纯内核不是有限执行器。10NumPy只在数组入口加载,参考入口及模块导入保持标准库核心的依赖边界。11"""1213# 已求值结果和冻结证据共享协议;这里不调用任一表达式或保持数值核。14from .expression_reference import Evaluation15from .numeric import ScalarValue16from .temporal import ConditionTick17from .types import QualityFlag as Q, SignalDType as D, Truth18# 参考轴先要求原生int,再沿用已有int64端点检查,不进行t-1或差分运算。19from ..timebase.conversion import require_int64_ns202122def _reference_truth(result):23    """把已经验证的BOOL标量转为三值,未知存储占位不参加真假判断。2425    参数: result当前Evaluation,调用入口已检查ScalarValue及BOOL声明。26    返回: Truth.TRUE、Truth.FALSE或Truth.UNKNOWN。27    异常: 无主动异常;调用者必须先完成typed结果校验。28    """29    # valid先于值解释,无效None/False等占位都只表示UNKNOWN。30    if not result.value.valid:31        return Truth.UNKNOWN32    # 只有已验证的原生BOOL正常值进入二值分支,不对任意数值使用truthiness。33    return Truth.TRUE if result.value.value else Truth.FALSE343536def condition_ticks_reference(times, before, continuous, point, actual_updates,37                              invalid_updates, observation_ends, terminals):38    """独立逐点组装完整条件证据,不从来源推断更新标志或补造时间。3940    参数:41        times: 原生int构成的tuple,单位ns,int64范围内严格递增。42        before/continuous/point: 同长Evaluation tuple,三个视图的结果dtype均为BOOL。43        actual_updates: 同长原生bool tuple,当前条件依赖中是否有真实更新。44        invalid_updates: 同长原生bool tuple,实际选中的更新样本是否无效;45            不把保持值因TTL到期而无效算作真实无效更新,True必须同时有actual。46        observation_ends: 同长原生bool tuple,条件依赖的来源是否在此刻结束观测。47        terminals: 同长原生bool tuple,会话连续域是否结束;至多唯一末项,48            不要求同时存在来源EOF,普通批次全False与空输入均合法。49    返回:50        tuple[ConditionTick, ...],保留连续/点质量、真实因果及当前依赖诊断。51    异常:52        TypeError为容器、原生元素、模型或非BOOL;ValueError为长度、回退/重复时间、53        非末terminal或invalid缺actual;OverflowError为时间越界;MemoryError为分配失败。54    副作用:55        只创建当前有限输入的输出模型,不修改任何输入;申请预算由调用者负责。56    """57    # 明确固定tuple协议,不能从任意迭代器隐式收集全量来源。58    columns = (before, continuous, point, actual_updates, invalid_updates, observation_ends, terminals)59    if type(times) is not tuple or any(type(column) is not tuple for column in columns):60        raise TypeError('参考条件证据需要时间、三视图及四标志tuple')61    # 行数必须已经对齐,禁止zip静默截断或广播修补错位证据。62    size = len(times)63    if any(len(column) != size for column in columns):64        raise ValueError('条件证据各输入长度必须相同')65    # 时间不接受bool/NumPy标量;直接比较避免极值差分或t-1溢出。66    previous = None67    for time in times:68        if type(time) is not int:69            raise TypeError('参考条件证据时间需要原生int纳秒')70        require_int64_ns(time)71        if previous is not None and time <= previous:72            raise ValueError('条件证据时间必须严格递增')73        previous = time74    # 四种标志不能用整数或字符串真假代替真实证据。75    for column in (actual_updates, invalid_updates, observation_ends, terminals):76        if any(type(value) is not bool for value in column):77            raise TypeError('参考条件证据标志需要原生bool')78    # 任一前置terminal都会违反唯一末组契约;普通批次允许完全没有terminal。79    if any(terminals[index] for index in range(max(0, size - 1))):80        raise ValueError('terminal只能唯一出现在输入末项')81    if any(invalid and not actual for invalid, actual in zip(invalid_updates, actual_updates)):82        raise ValueError('真实无效更新必须同时有actual_update')83    # Evaluation自身不验证字段,先核对真实标量/诊断协议与BOOL声明再解释值。84    for column in (before, continuous, point):85        for result in column:86            if (not isinstance(result, Evaluation) or not isinstance(result.value, ScalarValue)87                    or not isinstance(result.dependency_quality, Q)):88                raise TypeError('参考三视图需要typed Evaluation/ScalarValue/QualityFlag')89            if result.value.dtype is not D.BOOL:90                raise TypeError('条件证据三视图必须为BOOL,数值不能隐式转bool')91    # 参考逐点只使用当前三个结果;不调用数组实现或重新查询历史。92    ticks = []93    for index, time in enumerate(times):94        old, current, observed = before[index], continuous[index], point[index]95        old_state = _reference_truth(old)96        state, point_state = _reference_truth(current), _reference_truth(observed)97        # known更新前点、实际无效或新增结果质量位证明未知来自真实更新。98        causal = (invalid_updates[index] or old_state is not Truth.UNKNOWN99                  or bool(observed.value.quality & ~old.value.quality))100        actual_unknown = actual_updates[index] and point_state is Truth.UNKNOWN and causal101        # 半开连续域在真实terminal结束,但不更改闭区间当前点的证据。102        quality = current.value.quality103        if terminals[index]:104            state, quality = Truth.UNKNOWN, quality | Q.MISSING105        # 仅当前连续与当前点的依赖原因属于真实诊断,before反事实原因排除。106        diagnostic = current.dependency_quality | observed.dependency_quality107        ticks.append(ConditionTick(time, state, quality, actual_updates[index],108                                   observation_ends[index], terminals[index], point_state,109                                   observed.value.quality, actual_unknown, diagnostic))110    # 冻结输出供检测器按完整组推进;空输入自然得到空tuple。111    return tuple(ticks)112113114def condition_ticks_numpy(times, before, continuous, point, actual_updates,115                          invalid_updates, observation_ends, terminals):116    """独立按列构造因果与三值证据,最后仅恢复不可变ConditionTick模型。117118    参数:119        times: 精确ndarray,一维int64纳秒轴,严格递增。120        before/continuous/point: 同轴ArrayEvaluation,NumericArray逻辑dtype为BOOL。121        actual_updates: 精确ndarray,形状(N,)的bool真实更新列。122        invalid_updates: 同形状bool列,实际选中更新样本无效;TTL不属于真实更新,123            True必须有同时刻actual_updates=True。124        observation_ends: 同形状bool列,条件依赖的来源观测结束标志。125        terminals: 同形状bool列,会话连续域结束标志,至多唯一末项;126            不要求来源EOF同时成立,空轴及无terminal合法。127    返回:128        tuple[ConditionTick, ...];数值/因果计算整列完成,装箱不调用参考实现。129    异常:130        TypeError为数组布局、模型或非BOOL;ValueError为shape、非递增时间或矛盾标志;131        MemoryError为列/输出分配失败。不隐式cast、不调用vectorize或标量参考数值核。132    内存与副作用:133        临时状态/quality/因果/诊断列均为(N,),不修改借用的输入;预算须由调用者先申请。134    """135    # 延迟加载数组依赖,使只导入/使用参考入口时不引入NumPy。136    import numpy as np137    from .expression_numpy import ArrayEvaluation138    from .numeric_numpy import NumericArray139    # 轴的物理布局明确,不用asarray/astype隐式转换任意输入。140    if type(times) is not np.ndarray or times.ndim != 1 or times.dtype != np.dtype('int64'):141        raise TypeError('数组条件证据时间需要一维精确int64 ndarray')142    # 比较相邻坐标而非np.diff,INT64_MIN到INT64_MAX的合法递增不会回绕。143    if np.any(times[1:] <= times[:-1]):144        raise ValueError('条件证据时间必须严格递增')145    # 四标志是同形状bool列;禁止广播或对象数组真值进入因果运算。146    for column in (actual_updates, invalid_updates, observation_ends, terminals):147        if type(column) is not np.ndarray or column.ndim != 1 or column.dtype != np.dtype('bool'):148            raise TypeError('数组条件证据标志需要一维精确bool ndarray')149        if column.shape != times.shape:150            raise ValueError('条件证据标志与时间shape必须相同')151    # 终点只能是当前输入末项,真实无效标志必须有同时刻实际更新。152    if np.any(terminals[:-1]):153        raise ValueError('terminal只能唯一出现在输入末项')154    if np.any(invalid_updates & ~actual_updates):155        raise ValueError('真实无效更新必须同时有actual_update')156    # 三个静态视图复用已校验模型,仅检查本次BOOL和同轴布局;不复制或重新求值。157    for result in (before, continuous, point):158        if not isinstance(result, ArrayEvaluation) or not isinstance(result.value, NumericArray):159            raise TypeError('数组三视图需要typed ArrayEvaluation/NumericArray')160        if result.value.dtype is not D.BOOL:161            raise TypeError('条件证据三视图必须为BOOL,数值不能隐式转bool')162        if result.value.values.shape != times.shape or result.dependency_quality.shape != times.shape:163            raise ValueError('条件证据三视图与时间shape必须相同')164    # 因果来自实际invalid、更新前known或点结果新增质量位,整列掩码独立于参考。165    causal = (invalid_updates | before.value.valid166              | ((point.value.quality & ~before.value.quality) != 0))167    actual_unknown = actual_updates & ~point.value.valid & causal168    # 形状(N,)的整数状态列使用0/1/2对应TRUE/FALSE/UNKNOWN;无效False占位不决定真值。169    continuous_states = np.where(continuous.value.valid, np.where(continuous.value.values, 0, 1), 2)170    point_states = np.where(point.value.valid, np.where(point.value.values, 0, 1), 2)171    # 只修改新建连续列,terminal不延长面积;借用的点结果与质量保持原样。172    continuous_states[terminals] = 2173    quality = continuous.value.quality.copy()174    quality[terminals] |= np.uint16(Q.MISSING)175    # 当前实际诊断整列合并,刻意排除更新前反事实诊断。176    diagnostic = continuous.dependency_quality | point.dependency_quality177    # 列运算已完成,只在末端把形状(N,)存储恢复为原生int/bool及枚举模型。178    truths = (Truth.TRUE, Truth.FALSE, Truth.UNKNOWN)179    return tuple(ConditionTick(int(time), truths[int(continuous_states[index])], Q(int(quality[index])),180                               bool(actual_updates[index]), bool(observation_ends[index]), bool(terminals[index]),181                               truths[int(point_states[index])], Q(int(point.value.quality[index])),182                               bool(actual_unknown[index]), Q(int(diagnostic[index]))) for index, time in enumerate(times))183
Chronaxis 用户手册 · 离线阅读