Petri-net discovery and model alignment, BPMN control flow, XES/PNML exchange and process diagnostics
moon run examples/workload_windows --target wasm-gc --deny-warn| 新增核心能力 | 实际可复用的结果 |
|---|---|
| 可执行模型发现 | 经典 Alpha 从因果足迹发现含并行结构的接受 Petri Net;前缀网发现保留观察到的有限轨迹语言,支持重复活动和短循环样例,不将 DFG 换名为模型 |
| 模型级一致性 | 带权普通 P/T 网、初始/终止标识、静默迁移;Dijkstra 在轨迹与标识乘积空间返回最优同步/日志/模型偏差证据;预算不足显式报错 |
| 模型行为检查 | 可达状态图、终止可达、能否从已探索状态完成、剩余令牌完成异常、死锁与死迁移;未完成探索标记 complete=false,不冒充完整 soundness 证明 |
| BPMN 控制流接入 | 支持一个起止事件、普通 task、XOR/AND 分支及汇合的受限 BPMN 2.0 XML,转换成 Petri Net 后按语义检查;不执行条件、事件、数据或子流程 |
| 标准格式互操作 | XES 完成事件和 start/complete 配对、时间/资源/实例身份;PNML 带权网与明确终止标识;XML 双向交换,明确投影与不支持项 |
| 批量变体复用 | 同一模型、同一标签序列只搜索一次,逐实例重新绑定事件 ID;成本与证据与不复用版本一致,可统计实际搜索工作 |
moon run --target native examples/model_discovery
moon run --target native examples/model_conformance
moon run --target native examples/standard_workflow| 能力 | 可复用价值 |
|---|---|
| 日志重建与 JSON 互操作 | 将乱序业务区间按实例重建,验证身份、时间与容量,便于应用或现有协议库接入。 |
| 流程关系和变体发现 | 区分活动次数与实例覆盖,识别直接相邻关系、自循环、起止节点和完整处理路径。 |
| 最优加权轨迹对齐 | 对有限参考路径解释额外活动和缺失步骤,输出活动身份与逐步证据,支持不同偏差成本。 |
| 区间性能和资源诊断 | 区分服务工作量、并发区间覆盖和真正空闲,分析分位数、环节间隔及资源并发峰值。 |
import { "xingsiyi/processlens" @lens }fn main raise {
let log = @lens.EventLog::new([
@lens.LogEvent::new("o1", "order/7", "create", 0L, 1L),
@lens.LogEvent::new("o2", "order/7", "ship", 5L, 6L),
])
let model = @lens.ReferencePath::new("approved-order", ["create", "approve", "ship"])
let result = log.align([model])
assert_eq(result[0].cost, 1)
println(@lens.alignment_to_json(result[0]).stringify())
println(@lens.process_map_to_json(log.discover()).stringify())
println(@lens.performance_to_json(log.performance()).stringify())
}| 示例 | 输入、分析和可核验结果 |
|---|---|
| procurement | 两笔乱序订单,发现正常和跳过审批两种路径;对齐明确指出缺失审批,并报告处理空闲。 |
| support | 工单反复调查形成自循环;对齐给出多余活动证据,并输出客服环节服务耗时分布。 |
| pipeline | 构建与测试并行;区间并集避免把并发工作量误算成总耗时,计算资源并发峰值。 |
| repairs | 正常维修和复检返工走不同参考路径;识别变体,比较工位服务时间和跨工单并发。 |
moon run --target native examples/procurement
moon run --target native examples/support
moon run --target native examples/pipeline
moon run --target native examples/repairs
moon run --target native --release examples/process_scalemoon run --target native cmd/processlens -- analyze examples/files/process-log.json
moon run --target native cmd/processlens -- align examples/files/process-log.json examples/files/reference-paths.jsonmoon run --target native cmd/processlens -- check examples/files/model-log.xes examples/files/parallel.bpmn
moon run --target native cmd/processlens -- discover examples/files/model-log.xes alpha
moon run --target native cmd/processlens -- discover-pnml examples/files/model-log.xes prefix
moon run --target native cmd/processlens -- model examples/files/parallel.bpmn
moon run --target native cmd/processlens -- audit examples/files/model-log.xes examples/files/policies.json
python scripts/verify_model_cli.pymoon check --target all --deny-warn
moon build --target all --deny-warn
moon test --target all --deny-warn
moon fmt --check
moon info
git diff --exit-code
python scripts/verify_repository.pypub(all) suberror ProcessError {
InvalidLog(path~ : String, reason~ : String)
Capacity(resource~ : String, limit~ : Int)
} derive(Debug)pub struct AlignmentCosts {
unexpected : Int
missing : Int
}pub struct AlignmentSpec {
// private fields
}pub struct BpmnModel {
// private fields
}pub(all) struct CasePerformance {
case_id : String
events : Int
cycle_time : Int64
busy_union : Int64
idle_time : Int64
service_work : Double
overlapping_starts : Int
}pub struct CaseTrace {
// private fields
}fn CaseTrace::align(self : CaseTrace, references : Array[ReferencePath], costs? : AlignmentCosts, max_cells? : Int) -> TraceAlignment raise ProcessErrorfn CaseTrace::align_net(self : CaseTrace, net : PetriNet, limits? : ModelLimits) -> ModelAlignment raise ProcessErrorpub(all) struct CohortComparison {
before_cases : Int
after_cases : Int
total_variation : Double
variants : Array[VariantDelta]
}pub(all) struct DurationDistribution {
count : Int
minimum : Int64?
maximum : Int64?
median : Int64?
p95 : Int64?
mean : Double?
}pub struct EventLog {
// private fields
}fn EventLog::align(self : EventLog, references : Array[ReferencePath], costs? : AlignmentCosts, max_cells? : Int) -> Array[TraceAlignment] raise ProcessErrorfn EventLog::align_net(self : EventLog, net : PetriNet, limits? : ModelLimits, reuse_variants? : Bool) -> Array[ModelAlignment] raise ProcessErrorfn EventLog::check_policies(self : EventLog, policies : Array[ProcessPolicy], max_work? : Int, max_findings? : Int) -> Array[PolicyResult] raise ProcessErrorfn EventLog::compare_cohort(self : EventLog, next : EventLog) -> CohortComparison raise ProcessErrorfn EventLog::flow_windows(self : EventLog, from : Int64, until : Int64, width : Int64, max_windows? : Int, max_work? : Int) -> Array[FlowWindow] raise ProcessErrorfn EventLog::new(events : Array[LogEvent], max_events? : Int, max_cases? : Int, max_trace? : Int) -> EventLog raise ProcessErrorfn EventLog::resource_timeline(self : EventLog, resource : String, from : Int64, until : Int64, max_segments? : Int) -> Array[ResourceOccupancy] raise ProcessErrorfn EventLog::select_cases(self : EventLog, selection : CaseSelection) -> EventLog raise ProcessErrorpub(all) struct FlowWindow {
started : Int64
completed : Int64
cases_started : Int
cases_completed : Int
active_at_start : Int
active_before_end : Int
observed_work_area : Double
mean_observed_wip : Double
completed_cycles : DurationDistribution
}pub(all) struct HandoffPerformance {
source : String
target : String
positive_gap : DurationDistribution
overlapping_pairs : Int
}fn LogEvent::new(id : String, case_id : String, activity : String, started : Int64, completed : Int64, resource? : String?) -> LogEvent raise ProcessErrorpub(all) struct ModelLimits {
states : Int
edges : Int
tokens_per_place : Int
}pub(all) struct PerformanceReport {
cases : Array[CasePerformance]
activities : Array[ActivityPerformance]
handoffs : Array[HandoffPerformance]
resources : Array[ResourcePerformance]
cycle_times : DurationDistribution
}pub struct PetriNet {
// private fields
}fn PetriNet::fire(self : PetriNet, marking : Array[Int], transition : String) -> Array[Int] raise ProcessErrorfn PetriNet::new(places : Array[String], transitions : Array[NetTransition], arcs : Array[NetArc], initial : Array[PlaceTokens], accepting : Array[PlaceTokens]) -> PetriNet raise ProcessErrorpub(all) struct PolicyResult {
case_id : String
policy : String
status : PolicyStatus
event_ids : Array[String]
}pub(all) struct ProcessMap {
nodes : Array[ActivityNode]
edges : Array[FlowEdge]
variants : Array[ProcessVariant]
cases : Int
events : Int
}fn ProcessMap::frequent_edges(self : ProcessMap, minimum : Int) -> Array[FlowEdge] raise ProcessErrorpub(all) enum ProcessPolicy {
Response(id~ : String, trigger~ : String, target~ : String, within_ms~ : Int64?)
Precedence(id~ : String, trigger~ : String, required~ : String)
NotCoexist(id~ : String, first~ : String, second~ : String)
SeparationOfDuties(id~ : String, first~ : String, second~ : String)
}pub struct ReferencePath {
// private fields
}fn ReferencePath::new(name : String, activities : Array[String]) -> ReferencePath raise ProcessErrorpub(all) struct ResourceHandoff {
source : String
target : String
occurrences : Int
cases : Int
}pub(all) struct ResourceOccupancy {
started : Int64
completed : Int64
active : Int
}pub(all) struct ResourcePerformance {
resource : String
occurrences : Int
service : DurationDistribution
maximum_concurrency : Int
}pub(all) struct TraceAlignment {
case_id : String
reference : String
cost : Int
fitness : Double
moves : Array[AlignmentMove]
evaluated_cells : Int
}Install
Download zipPetri-net discovery and model alignment, BPMN control flow, XES/PNML exchange and process diagnostics